PLUS Scraper
Pricing
from $1.50 / 1,000 products
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
15 hours ago
Last modified
Categories
Security
Limited permissionsShare
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?
| Data | Fields | Filled in last full run |
|---|---|---|
| Identity | externalId, name, brand, ean, gtins | 100%: every product has its barcode |
| Size | sizeText, packCount, quantity, unit | 99.5% |
| Price | price, currency, unitPrice, unitPriceUnit | 100% price, 99.5% unit price |
| Deals | promoPrice, promoText, promoType, promoStart, promoEnd | 1,587 products on a deal (9.2%), all with dates |
| Product facts | organic, badges, storeOnly | 100% organic flag (1,030 organic), 240 store-only |
| With details | nutriScore, vegan, vegetarian, deposit, quality logos in badges | with withDetails: Nutri-Score 28.5% (4,931), vegan 2,875, vegetarian 4,517, deposit 1,048 |
| Category | categoryPath, category | 100% |
| Links and stock | url, imageUrl, inStock | 100% 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,promoEndand 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,vegetarianandorganicwithwithDetails. - 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.
| Event | Price |
|---|---|
| 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
| Scenario | Products | Cost |
|---|---|---|
Small test, maxItems: 100 | 100 | $0.15 |
Keyword search, keywords: ["halfvolle melk"] | 57 | $0.09 |
Same search with withDetails | 57 | $0.14 |
This week's deals, onlyBonus: true | 1,587 | $2.38 |
| Full catalog | 17,326 | $25.99 |
| Full catalog with details | 17,326 | $43.32 |
| Full catalog every week, 4 runs a month | 69,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?
| Field | Type | Default | Meaning |
|---|---|---|---|
keywords | array of strings | empty | Search for these words instead of reading the full catalog. |
eans | array of strings | empty | Look up these barcodes instead of reading the full catalog. |
onlyBonus | boolean | false | Keep only products on a deal, in any mode. |
withDetails | boolean | false | Add each product's details: Nutri-Score, vegan, vegetarian, deposit, quality logos, from the actor's details file. |
freshDetails | boolean | false | With withDetails: read every product's details live from PLUS, with in-store availability. |
maxItems | integer | 100000 | Stop after this many products. The default covers the full catalog. |
minItems | integer | 1 | Fail 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.
| Field | Source | Meaning |
|---|---|---|
chain | Fixed | Always plus. |
store | Fixed | Always null: plus.nl's prices with no store chosen. |
externalId | PLUS | PLUS product id, such as 454439. |
ean | File | Barcode, mostly EAN-13. |
gtins | Derived | The barcode in a list, for the same field on other chains. |
name | PLUS | Product name. |
brand | PLUS | Brand. |
sizeText | PLUS | Size as PLUS writes it, such as Per 750 ml or Per 30 st. |
packCount | Derived | Units in a multipack; 1 when not a multipack. |
quantity | Derived | Size of one unit: Per 750 ml gives 750. |
unit | Derived | Unit of quantity: g, kg, ml, cl, l, stuk or m. |
price | PLUS | Regular price in EUR. |
currency | Fixed | Always EUR. |
unitPrice | Derived | Regular price per kg, litre, piece or metre, equal to PLUS's own on 99.6% of products. |
unitPriceUnit | Derived | Unit of unitPrice: kg, l, stuk or m. |
promoPrice | PLUS | Deal price in EUR, rounded to the cent, when lower than price. |
promoText | PLUS | The deal as shown, such as 30 % KORTING, 1+1 GRATIS or 2 VOOR 2.99. |
promoType | PLUS | PLUS's second label, such as OP=OP. |
promoLabels | Fixed | Always null on PLUS; kept for the same field on other chains. |
promoStart | PLUS | First day of the deal, YYYY-MM-DD. |
promoEnd | PLUS | Last day of the deal, YYYY-MM-DD. |
organic | Derived | true when in PLUS's organic filter, named organic, or with an organic logo in the details. |
nutriScore | PLUS | Nutri-Score A to E, with withDetails. |
badges | PLUS | PLUS's logos, such as Laagblijver; with withDetails also VEGAN, Beter Leven 1 Ster, MSC Label. |
vegan | Derived | Vegan logo (with withDetails) or vegan in the name. |
vegetarian | Derived | Vegetarian logo (with withDetails), vegan, or vegetarisch in the name. |
deposit | PLUS | Deposit (statiegeld) logo, with withDetails; otherwise null. |
storeOnly | PLUS | true when sold in PLUS shops only, not online. |
categoryPath | PLUS | Category path, such as Zuivel, eieren, boter/Melk/Houdbare melk. |
categoryIds | Fixed | Always null: PLUS gives no category ids. |
category | PLUS | Top-level category. |
url | Derived | Product page on plus.nl. |
imageUrl | PLUS | Product image. |
inStock | PLUS | true when the product can be ordered online. |
availabilityLabel | Fixed | Always null on PLUS. |
detailsRead | Derived | true when the product's details are in the item, from the details file or read live (withDetails). |
detailsDate | Derived | Date the details were read: the details file's date, or the run's date when read live. |
searchTerm | Input | The keyword or barcode that found the product; null in full-catalog mode. |
scrapedAt | Fixed | Time 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": []}
| Field | Meaning |
|---|---|
itemsPushed, distinctIds | Products stored. Only products Apify accepted count. |
productsRead | Distinct products read from PLUS, including those left out by onlyBonus, maxItems or your charge limit. |
expectedTotal, coverage | PLUS's own product count, and productsRead / expectedTotal. null in search mode. |
organicCount | Products in PLUS's organic filter. |
barcodesFromFile | Barcodes taken from the file the actor carries. |
barcodesFetched | Barcodes read from PLUS in this run, for products new since the file was written. |
barcodesMissing | Products without a barcode. |
detailsRead | Products whose details were read live in this run. |
detailsFromFile, detailsFileDate | Products whose details came from the actor's details file, and the file's date. |
searches | In search mode, PLUS's count and the collected count per keyword or barcode. |
stoppedAtChargeLimit | true when the run stopped at your maximum charge. |
blocked | true when PLUS refused twice in a row (HTTP 403); the run then fails with the products it already had. |
concurrencyReduced | true when PLUS answered 403 or 429; the actor then sends fewer requests at a time. |
versionsRefreshed | Times the actor re-read PLUS's site version, because PLUS released during the run. |
statusCodes, retries, errors | Every 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 Scraper | studio-amba/plus-nl-scraper | harvestedge/dutch-supermarkets-all-11 | |
|---|---|---|---|
| Price per 1,000 | $1.50, details $1.00 | from $1.20 on top plans, $2.00 on free | $5.00 |
| Full catalog | yes, default | no, one keyword per run | no, keyword search |
| EAN barcode | yes, every product | yes, can be empty | no |
| Barcode lookup | yes, eans | no | no |
| Deal dates | yes | no | no |
| Nutri-Score, vegan, deposit | yes, withDetails | no | no |
| Organic flag | yes | no | no |
| Completeness check against PLUS's count | yes, every run | no | no |
| Proxy | none needed | NL residential by default | not 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
withDetailsthe 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.99or1+1 GRATISleave the single price unchanged; the deal is inpromoText. - 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. unitPricematches 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 DarkandVegetarische Slagerproducts, have no logo at PLUS; a vegan product is vegetarian too, though 1,168 lack PLUS's vegetarian logo. WithoutwithDetails, only the name counts, and the fields are otherwisenull. - 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'sEU Organic Farminglogo 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:inStockthen comes from the product list, as without details.freshDetailsreads every detail live, with availability. - PLUS gives no category ids, so
categoryIdsisnull. Seasonal categories such asKerstandSinterklaasappear in their season.
Is it legal to use the PLUS Scraper?
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
| Actor | What it extracts | Price per 1,000 | |
|---|---|---|---|
| PLUS Scraper | PLUS products: prices, deals with dates, EAN, Nutri-Score, vegan | $1.50 | you are here |
| Albert Heijn Scraper | Albert Heijn products: prices, Bonus deals, EAN, Nutri-Score | $1.00 | |
| Jumbo Scraper | Jumbo products: prices, deals with dates, EAN, organic, shelf life | $1.50 | |
| Dirk Scraper | Dirk products: prices, next week's deals, EAN, Nutri-Score | $2.00 | |
| DekaMarkt Scraper | DekaMarkt products: prices, next week's deals, EAN, organic | $2.00 | |
| Hoogvliet Scraper | Hoogvliet products: prices, next week's deals, EAN, ingredients, vegan | $2.00 | |
| Vomar Scraper | Vomar products: prices, every EAN barcode, BIO, categories | $1.00 | |
| Poiesz Scraper | Poiesz products: prices, deals with dates, EAN, deposit, ingredients | $1.50 | |
| Ekoplaza Scraper | Ekoplaza products: prices, next week's deals, EAN, allergens, Ekoscope | $2.00 | |
| Aldi NL Scraper | Aldi 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.