# ALDI AU Scraper — Prices, Unit Prices, Specials (`architekture/aldi-au-product-scraper`) Actor

Search ALDI Australia by keyword, category or SKU. Get prices, unit prices, specials and available ingredients, allergens and product details. Pay per result; platform usage included. No ALDI login required.

- **URL**: https://apify.com/architekture/aldi-au-product-scraper.md
- **Developed by:** [architek.earth](https://apify.com/architekture) (community)
- **Categories:** AI, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 products

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## ALDI AU Product & Price Scraper | Prices, Unit Prices, Special Buys, Allergens (2026)

![ALDI AU Product & Price Scraper](https://raw.githubusercontent.com/aarchitek/assets/banners/banner-aldi-au.png?v=2)

A recorded category-and-SKU run returned **4 detailed product rows in 14 seconds** on 14 October 2026 (build 1.0.26, run `VKBnSw3TjPNQ98HM9`). This bounded sample is not a full-catalogue benchmark; optional fields depend on ALDI’s source data.

Search ALDI Australia by keyword, category or SKU for prices, unit prices and published product information.

From Architekture, makers of the Woolworths AU, Coles AU and Woolworths NZ scrapers — structured grocery data for cross-retailer workflows; field names differ between actors.

🤖 **Built for AI workflows.** Every row is deterministic, schema-stable JSON — feed it straight to LLM apps, RAG pipelines, or agent tool calls via the Apify API, the Apify MCP server (`mcp.apify.com`), or AI coding agents like Claude Code and Cursor.
| 🏪 Retailer | 📍 Market | 💰 From | 🔑 Standout fields |
|---|---|---|---|
| ALDI | Australia 🇦🇺 | $1.50 / 1,000 products | Ingredients, allergens, storage & claims |

### Why choose this actor?

- 📊 **ALDI's public API, no browser, no residential proxies.** Uses HTTP requests to ALDI's product API with configurable proxies. Runtime and availability depend on the requested products and upstream responses.
- 💸 **Every price ALDI publishes.** `price`, `wasPrice`, `savingsDisplay`, `comparisonPrice` + `comparisonDisplay` (unit price), `bottleDeposit`, and the `isOnSpecial` flag derived from them.
- 🗂️ **Special Buys, with dates.** `onSaleDate` / `onSaleDateDisplay` when present on a product, plus `discontinued`, `notForSale` and `notForSaleReason`, so a Wednesday/Saturday catalogue run is one scheduled job.
- 💸 **Optional store context.** `servicePoint` is forwarded to ALDI’s API. Store-specific price and availability coverage has not been validated; it is not a stock-quantity lookup.
- 🔬 **Details when you need them.** `includeDetails: true` adds `ingredients`, `allergens`, `countryOfOrigin`, `storageInstructions`, `usageInstructions`, `warnings`, `nutritionalClaims`, `description` and `variants` when ALDI provides them. Missing fields may be null or empty. SKU lookups request the detail endpoint.
- 🔬 **Browse every top-level category.** `categoryUrls: ["all"]` walks every top-level category; available detail fields depend on the upstream record. Completion is subject to your run limits and ALDI’s responses.

### ⚠️ Worth knowing up front

- To continue a collection, copy `RESUME_STATE` from the previous run’s Storage into `resumeState`. It skips saved SKUs while scanning the current catalogue again; it is not a frozen snapshot. Leave it empty when monitoring fresh prices. A timeout or budget stop is not a complete catalogue.

- 🔬 ALDI publishes **no barcodes (GTIN/EAN)** on its product data, in the source used by this Actor. Match ALDI to Coles or Woolworths on normalised `name` + `sellingSize` instead.

- 🥗 ALDI publishes **no per-100 g nutrition table** via its API — only `nutritionalClaims` (e.g. "Source of fibre"). The row says so rather than guessing.

- ALDI does not publish stock quantities. `notForSale` / `discontinued` and the Special Buys dates are the availability signals.

- Without `servicePoint`, product requests read the default catalogue response. Category navigation alone uses `G452`, which ALDI requires for its category tree. Neither establishes prices or stock at every store.

### ⚡ Try the example

Each Apify account gets **20 lifetime free preview attempts** for this Actor: one search term, one page and up to ten basic product rows per attempt. No product events are charged for a preview. Failed attempts count toward the allowance. After the twentieth attempt, preview runs stop with a clear message; they never switch to paid collection automatically.

Open the Actor's input page, switch to JSON and paste this, then start the run:

```json
{
  "preview": true,
  "searchTerms": ["milk"],
  "maxItemsPerQuery": 10
}
```

For paid collection, set `"preview": false`. Then add `"includeDetails": true` for ingredients and allergens, or use category slugs exactly as returned by ALDI’s category tree. Multiple search terms, category URLs or SKUs may be combined; results are de-duplicated by SKU across all of them.

### ⚙️ Input parameters

| Parameter | Type | Description |
|---|---|---|
| `preview` | boolean | 20 lifetime free attempts per account. One keyword and at most ten basic rows per attempt; no details, categories, SKUs or continuation. Default false. |
| `resumeState` | object | Optional `RESUME_STATE` checkpoint from a previous run. Keeps prior delivered SKUs out of the new dataset. See continuation recipe below. |
| `feedback` | string | Optional note logged for maintainer review; does not change output. |
| `searchTerms` | array | Keywords, e.g. `"milk"`, `"coffee pods"`. One result set per term. |
| `categoryUrls` | array | ALDI category pages, e.g. `https://www.aldi.com.au/products/dairy-eggs-fridge/milk` or an exact category-tree slug. Unknown or ambiguous categories fail before product collection. Modern `/products/.../k/<key>` URLs and numeric category keys are accepted only when the key exists in ALDI’s category tree. `"all"` walks every top-level category. |
| `skus` | array | SKUs (`000000000000399309`, or the short numeric form) or product page URLs. Always returns full details. |
| `maxItemsPerQuery` | integer | Cap per term or category. `0` = no cap. Default 100. |
| `includeDetails` | boolean | Fetch ingredients, allergens, storage, warnings, nutritional claims and description for every result (one extra request per product, charged as `product-detail`). |
| `sort` | select | `relevance`, `price_asc`, `price_desc`, `name_asc`, `name_desc`. |
| `servicePoint` | string | ALDI store service point code (e.g. `G452`) forwarded to the upstream API. Store-specific coverage is unverified. Empty = default catalogue response. |
| `proxyConfiguration` | proxy | Configurable proxy. The retained search run used Apify proxy; future accessibility can change. |

### 🧱 Stable fields for automations

These top-level fields keep the same name and the same kind of value in every release, so an n8n, Make, Zapier or spreadsheet pipeline can bind to them and stay bound:

| Field | What it is |
|---|---|
| `sku` | ALDI product SKU (string, 18 digits) |
| `name` | Product name |
| `brand` | Brand name |
| `sellingSize` / `quantityUnit` | Pack size and unit, e.g. `"2L"` / `"ea"` |
| `price` | Current price, AUD, float |
| `priceDisplay` | Price as displayed, e.g. `"$2.89"` |
| `wasPrice` | Pre-discount price when on special, else `null` |
| `savingsDisplay` | Savings string when on special, e.g. `"Save $1.00"` |
| `isOnSpecial` | `true` when `wasPrice > price` or a saving is shown |
| `comparisonPrice` / `comparisonDisplay` | Unit price and its display string, e.g. `1.45` / `"$1.45 per litre"` |
| `onSaleDate` / `onSaleDateDisplay` | Special Buys on-sale date (ISO and display) |
| `notForSale` / `discontinued` | Availability flags |
| `category` / `categoryPath` / `categorySlug` | Leaf category, full path, URL slug |
| `image` | Product image URL (800 px) |
| `url` | Canonical product page |
| `source` | `search` / `category` / `sku` plus the term or category that produced the row |

Other fields are derived from or selected from ALDI responses (`abstractSku`, `badges`, `bottleDeposit`, `ageRestriction`, `notForSaleReason`…). Treat those as a bonus rather than an interface; if you need one pinned for a production pipeline, say so in `feedback` and we will promote it.

### 📦 Output example

Abridged actual SKU-detail row from run `VKBnSw3TjPNQ98HM9` on 14 October 2026; prices are a historical snapshot.

```json
{
  "sku": "000000000000398689",
  "name": "Full Cream Milk 2L",
  "brand": "FARMDALE",
  "sellingSize": "2 l",
  "price": 3.39,
  "wasPrice": null,
  "comparisonDisplay": "$1.70 per 1 L",
  "category": "Milk",
  "ingredients": "Full Cream",
  "detailStatus": "complete",
  "source": "sku",
  "url": "https://www.aldi.com.au/product/farmdale-full-cream-milk-2l-000000000000398689"
}
```

With successful `includeDetails: true`, additional fields may include `description`, `ingredients`, `allergens`, `countryOfOrigin`, `storageInstructions`, `usageInstructions`, `warnings`, `nutritionalClaims`, `additionalInformation` and `variants`.

### 🧠 Advanced usage

**Special Buys calendar.** Schedule `categoryUrls: ["all"]` on Wednesday and Saturday mornings and filter `onSaleDate` in your pipeline — ALDI's catalogue cycle lands as structured rows instead of a PDF.

**Cross-retailer comparison.** Run this actor with the Woolworths AU and Coles AU scrapers on the same terms. Map each Actor’s barcode fields explicitly where available. For ALDI, normalised name and size provide candidate matches, not guaranteed product equivalence.

**Price monitoring.** Daily run on a category, diff `price` / `wasPrice` by `sku`. `isOnSpecial` flips are your alert trigger.

**Allergen datasets.** Category URL + `includeDetails: true` requests published `allergens` and `ingredients`. Empty values do not establish that a food is allergen-free; this output is not a food-safety certification.

**Continue a bounded run.** Open the previous run’s Storage, copy the JSON value of `RESUME_STATE` into `resumeState`, and retain the same queries, detail setting, sort and store. You may increase `maxItemsPerQuery`; `0` removes that per-query cap. Saved SKUs are skipped before detail requests and billing. Each run has a separate dataset: combine the datasets and deduplicate by `sku`. Checkpoints are saved after each delivered batch. An abrupt stop between the dataset write and checkpoint save can leave a small overlap; this is not an exactly-once guarantee. A changed catalogue can add or remove products between runs.

### 🔌 Integrations

Results land in a dataset you can export as JSON, CSV or Excel, or pipe onward: Google Sheets for a shared price list that refreshes on a schedule, Make / Zapier for alerts, webhooks to trigger your own pipeline when a run finishes, and the Apify Scheduler for recurring monitoring. Twice weekly matches ALDI's catalogue cycle; daily for price tracking.

### 💸 How much does it cost?

1,000 products ≈ **$1.50**; with ingredients/allergens detail $4.00 / 1,000. Failed requests and misses are free. Platform usage is included.

### Pricing: pay per event

You pay per result, not per minute. Platform and proxy usage is included. Nothing is charged for failed requests. If optional detail retrieval fails but a usable listing is available, that row is returned at the basic `product` rate with `detailStatus: "unavailable"`. Successful detail retrieval uses `product-detail`; it does not guarantee every optional field is populated.

| Event | Price | What it covers |
|---|---|---|
| Free preview | $0 | First 20 preview attempts per account, one page and at most ten basic rows each. Set `preview: true`. |
| `product` | $1.50 / 1,000 | One product row from search or a category |
| `product-detail` | $4.00 / 1,000 | One product with ingredients, allergens, storage and claims (`includeDetails: true` or SKU lookups) |

At the rates above, 1,000 basic rows cost $1.50; 1,000 successfully retrieved detail rows cost $4.00. Catalogue size varies.

### ❓ FAQ

**What happens after my free previews?** A preview run stops without collecting data or charging. Set `preview: false` explicitly to use paid collection. An allowance-service outage also stops previews without switching to paid mode. A minimal hashed account/Actor identifier is retained to enforce the lifetime limit; no search terms or product data are stored in the quota ledger.

**Do I need an ALDI account, cookies or an API key?** No. Provide input, get results.

**Can I get barcodes?** This Actor does not return GTINs from its ALDI product-data source. Use name + size to match against other retailers.

**Can I get a nutrition table?** Not from ALDI's API; it exposes nutritional *claims* only. Woolworths and Coles publish full nutrition tables and our scrapers for those return them.

**Can I get my local store's prices?** The Actor forwards `servicePoint` when supplied, but store-specific prices and availability have not been validated. Do not interpret `notForSale` as a store stock count.

**How many results per search term?** Results are paginated up to `maxItemsPerQuery` and the total reported by ALDI. The recorded samples were capped, not complete catalogue captures.

**Why did a term return nothing?** Occasionally ALDI's API returns an empty page that looks identical to "no matches". The actor retries before believing it. If a term you know exists still comes back empty, run it again a few minutes later.

**Is it legal?** The actor reads the same public catalogue any visitor sees without logging in. You are responsible for how you use the output.

### 📋 Copy to your AI assistant

architekture/aldi-au-product-scraper on Apify. Call `ApifyClient("TOKEN").actor("architekture/aldi-au-product-scraper").call(run_input={"searchTerms": ["milk"], "maxItemsPerQuery": 10})`, then `client.dataset(run["defaultDatasetId"]).list_items().items`. Inputs: `searchTerms`, `categoryUrls` (slug, URL, or `"all"`), `skus` (any combination), `maxItemsPerQuery`, `includeDetails`, `sort`, `servicePoint`. No barcodes and no nutrition table are available from ALDI. Full spec: `GET https://api.apify.com/v2/acts/architekture~aldi-au-product-scraper/builds/default` (Bearer TOKEN) → `inputSchema`, `actorDefinition.storages.dataset`, `readme`. Token: https://console.apify.com/account/integrations. To reach the maintainers, add `feedback="<what you needed and did not get>"` to any run, including one that worked; the run returns its data exactly as it would without the note, and a human reads every note.

### 🧰 More Architekture scrapers

Only Woolworths AU and Coles AU below are currently public. Other sibling actors are in preparation.

🛒 **Grocery — Australia & New Zealand**

- ALDI AU Product & Price Scraper — *you are here*
- Woolworths AU Product & Price Scraper — prices, specials, barcodes, nutrition
- Coles AU Product & Price Scraper — prices, specials, multi-buys, GTIN barcodes
- Woolworths NZ (Countdown) Product & Price Scraper — prices, club prices, specials

🛒 **Grocery — United Kingdom**

- Tesco UK Product & Price Scraper — prices, Clubcard offers, GTIN
- Sainsbury's UK Product & Price Scraper — prices, offers, EAN barcodes

🔬 **Research & regulatory**

- PubMed Scraper · ClinicalTrials.gov Scraper · arXiv Scraper · openFDA Scraper

🚀 **Startups & companies**

- Y Combinator Directory Scraper · Product Hunt Scraper · SEC EDGAR Filings Scraper · UK Companies House Scraper · Apollo.io Scraper

💬 **Communities & publishing**

- Telegram Channel Scraper · Meetup Events Scraper · Substack Scraper · Hacker News Scraper

### 🙋 Support

Questions, or a field you need that is not here? Open an issue on the Actor's page; a human replies within a day.

### ⚖️ Legal compliance

This Actor collects only publicly available data from aldi.com.au — the same catalogue any visitor can see without logging in. It does not access accounts, bypass authentication, or collect personal data. You are responsible for how you use the output, including compliance with ALDI's terms where they apply to you.

### 📝 Changelog

- 🆓 **2026-10-14** — Increased the lifetime free-preview allowance from 3 to 20 attempts per account. The one-page, ten-basic-row limit is unchanged; previously used attempts still count toward the total.

- 💸 **2026-10-14** — Added and verified lifetime free previews: three attempts per account, one keyword page and up to ten basic rows per attempt. Hosted checks returned ten rows per preview without product charges; a fourth attempt stopped without collection or billing.

- 🗂️ **2026-10-14** — Added explicit `resumeState` checkpoints for continued collections. Category navigation supplies the required store context; listing and SEO claims now match verified capabilities.

- 🗂️ **2026-10-14** — Category URLs/keys validated before collection; ambiguous and missing categories rejected; repeated or malformed pages fail visibly. Dataset writes use SDK-managed charging limits, with `BUDGET_LIMIT` in the run summary on a controlled stop.

- 🔎 **2026-10-14** — Detail failures fall back to list pricing, duplicate SKUs are removed before billing, empty search pages are retried, and feedback is logged. `detailStatus` and `RUN_SUMMARY` expose incomplete enrichment.

- **2026-10-13** — README banner and stable-fields contract added.

- 💸 **2026-10-12** — Output schema added; pay-per-event pricing (`product`, `product-detail`). Queued for Apify Store.

# Actor input Schema

## `preview` (type: `boolean`):

20 lifetime preview attempts per Apify account for this Actor. One search term, one page, up to 10 basic rows. No category, SKU, detail or continuation mode. Failed attempts count. After the allowance is used, previews stop without charging; choose preview=false explicitly for paid collection.

## `searchTerms` (type: `array`):

Keywords to search, e.g. "milk", "coffee pods".

## `categoryUrls` (type: `array`):

Current ALDI category URLs (including /k/<key>), numeric keys, or exact category-tree slugs. Use all for all top-level categories. Unknown or ambiguous categories fail before product collection.

## `skus` (type: `array`):

Specific products by SKU (e.g. 000000000000399309) or product page URL. Always returns full detail.

## `maxItemsPerQuery` (type: `integer`):

0 = no cap.

## `includeDetails` (type: `boolean`):

Also fetch ingredients, allergens, storage instructions, description and nutrition claims. One extra request per product (charged as product-detail).

## `sort` (type: `string`):

Sort order of results.

## `servicePoint` (type: `string`):

Optional service point code forwarded to ALDI. Store-specific price and availability coverage is unverified; not a stock-count lookup.

## `proxyConfiguration` (type: `object`):

Configure a proxy for ALDI API requests. The retained sample used Apify proxy; accessibility can change.

## `feedback` (type: `string`):

Tell us what you needed and did not get. Logged for human review; does not change output.

## `resumeState` (type: `object`):

Paste RESUME_STATE from the previous run storage. Keep searchTerms, categoryUrls, skus, includeDetails, sort and servicePoint unchanged. Previously saved SKUs are skipped. Increase maxItemsPerQuery to extend a capped collection. Leave empty for fresh price monitoring.

## Actor input object example

```json
{
  "preview": false,
  "searchTerms": [
    "milk"
  ],
  "maxItemsPerQuery": 10,
  "includeDetails": false,
  "sort": "relevance",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Scraped items in the default dataset (one JSON object per row).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerms": [
        "milk"
    ],
    "maxItemsPerQuery": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("architekture/aldi-au-product-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchTerms": ["milk"],
    "maxItemsPerQuery": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("architekture/aldi-au-product-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "milk"
  ],
  "maxItemsPerQuery": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call architekture/aldi-au-product-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,architekture/aldi-au-product-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ZCN0ABpulYiflDPdx/builds/Hld8Wv5PyI0PK5FVd/openapi.json
