Comparing pasta prices across Albert Heijn, Jumbo, and Plus
This compares pasta prices across three Dutch supermarkets — Albert Heijn, Jumbo, and Plus — using Pepesto's /catalog endpoint for each. The output is a product-by-product price table showing which chain is cheapest per 100g.
Run this yourself
$ PEPESTO_API_KEY=your_key node albert-heijn-price-comparison-nl.jsFull script: albert-heijn-price-comparison-nl.js. You'll need an API key to run it — get one here.
Getting started
One Pepesto API key, three catalog calls. The /catalog endpoint is the same regardless of country — just change the domain.
const res = await fetch('https://s.pepesto.com/api/link', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: 'bas@example.nl' }),
});
const { api_key } = await res.json();
// export PEPESTO_API_KEY=pepesto_live_...Important caveat: /catalog is an expensive call, so our advice is to cache the three JSON files locally or in your environment. Call the API once per day (or week depending on your use case), cache, and then re-runs against the cached files are instant.
The first call — fetching three catalogs in parallel
All three fetches run concurrently with Promise.all — there's no dependency between them.
const API_KEY = process.env.PEPESTO_API_KEY;
async function fetchCatalog(domain) {
const res = await fetch('https://s.pepesto.com/api/catalog', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`,
},
body: JSON.stringify({ supermarket_domain: domain }),
});
const data = await res.json();
return data.parsed_products;
}
const [ahProducts, jumboProducts, plusProducts] = await Promise.all([
fetchCatalog('ah.nl'),
fetchCatalog('jumbo.com'),
fetchCatalog('plus.nl'),
]);A typical AH catalog product looks like this:
{
"https://www.ah.nl/producten/product/wi101132/ah-biologisch-kastanjechampignons": {
"entity_name": "Button mushrooms",
"tags": ["bio"],
"names": {
"en": "AH Organic chestnut mushrooms",
"nl": "AH Biologisch Kastanjechampignons"
},
"price": 219,
"currency": "EUR",
"quantity_str": "250g",
"quantity": { "Unit": { "HundredGrams": 2 }, "accurate_grams": 250 }
}
}The quantity.Unit.HundredGrams field is what makes per-100g price calculation possible. If present, divide price by HundredGrams to get the normalised price. Products sold by piece (bread, individual cucumbers) don't have this field and get skipped.
const PASTA_KEYWORDS = [
'pasta', 'spaghetti', 'penne', 'fusilli', 'rigatoni',
'tagliatelle', 'farfalle', 'linguine', 'macaroni', 'lasagne',
];
function filterPastaProducts(products) {
const results = [];
for (const [url, product] of Object.entries(products)) {
const searchText = [
product.entity_name,
product.names?.en,
product.names?.nl,
].join(' ').toLowerCase();
const isPasta = PASTA_KEYWORDS.some(kw => searchText.includes(kw));
if (!isPasta) continue;
const hundredGrams = product.quantity?.Unit?.HundredGrams;
if (!hundredGrams || hundredGrams === 0) continue;
results.push({
name: product.names?.en || product.names?.nl,
nameDutch: product.names?.nl || '',
priceCents: product.price,
pricePer100g: product.price / hundredGrams,
quantityStr: product.quantity_str,
promo: !!product.promo,
promo_percentage: product.promo_percentage || 0,
});
}
return results.sort((a, b) => a.pricePer100g - b.pricePer100g);
}What the data showed
AH's own-brand pasta came out cheapest per 100g across all three stores — but Jumbo's branded range (De Cecco, Barilla) was significantly cheaper than the same brands at AH. The choice depends on whether you're buying own-brand or branded.
Plus had the fewest pasta SKUs in the sample. Their own-brand pasta was mid-range — not particularly cheap — and their branded range was limited.
Per-100g prices ranged from about €0.12 for cheap own-brand spaghetti to €0.60+ for premium organic pasta. Lea & Perrins Worcestershire sauce at AH (€2.29) is notable — significantly cheaper than specialty stores for the same product. The Jumbo catalog also carries Akfa Tomato Puree 420g at €2.39, useful if you're building a basket around pasta sauce.
Next steps
With the catalog data filtered to pasta products, the logical extension is building a cross-supermarket shopping list. If the cheapest pasta is at Jumbo, the cheapest olive oil is at AH, and the cheapest canned tomatoes are at Plus — the data tells you where to optimise. For practical shopping that's obviously annoying (three separate orders), but it's useful for deciding which supermarket to use as your primary shop for a given meal plan.
The catalog data also supports /products-style workflows: if you find a pasta you like in the catalog, the URL is the product ID you'd use to build a session for that specific SKU.
The result
This data shows a clear split: AH is cheaper for own-brand staples, Jumbo is better for branded items and runs more promotions. The two stores are complementary — which one "wins" depends entirely on what's in the basket, and the results might be different when you run the queries.
What else you could do?
Three natural extensions. Expand beyond pasta to all dry goods and compare AH vs Jumbo vs Plus across the full category — a single product type only scratches the surface. Add week-over-week price tracking: if AH's own-brand spaghetti goes up 10% in two weeks, the diff flags it automatically. Add REWE to the comparison — REWE stores are accessible from the Netherlands near the German border, and the same /catalog call works for shop.rewe.de.