{
  "openapi": "3.0.1",
  "info": {
    "title": "ALDI AU Scraper - Groceries, Special Buys & Prices",
    "description": "Scrape ALDI Australia (aldi.com.au) products: name, brand, price, was-price, savings, unit price, size, category, images, availability and Special Buys on-sale date, plus full detail (ingredients, allergens, nutrition). Search by keyword or category, filter by brand/theme, or paste any ALDI URL.",
    "version": "1.0",
    "x-build-id": "mlCPHgwim6P4eMVAy"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~aldi-com-au-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-aldi-com-au-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/abotapi~aldi-com-au-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-aldi-com-au-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/abotapi~aldi-com-au-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-aldi-com-au-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "search",
              "url"
            ],
            "type": "string",
            "description": "How to find products. 'search' builds listings from search terms and/or categories with filters; 'url' scrapes ALDI product, category or search URLs you paste.",
            "default": "search"
          },
          "searchTerms": {
            "title": "Search terms",
            "type": "array",
            "description": "Keywords to search the ALDI catalogue, e.g. 'milk', 'coffee', 'air fryer'. Each term is paginated fully (up to Max products). Leave empty to use categories instead.",
            "items": {
              "type": "string"
            }
          },
          "categories": {
            "title": "Categories",
            "type": "array",
            "description": "Category names or URL slugs to list, e.g. 'Special Buys', 'Limited Time Only', 'Lower Prices', 'Super Savers', 'Dairy Eggs & Fridge', 'meat-seafood/beef'. Also accepts a raw numeric category key. Special Buys and weekly-specials ranges are categories here. Leave empty to use search terms instead.",
            "items": {
              "type": "string"
            }
          },
          "specialsCategory": {
            "title": "Specials / offers range",
            "enum": [
              "",
              "special-buys",
              "lower-prices",
              "super-savers"
            ],
            "type": "string",
            "description": "Scrape a promotional range directly (search mode). ALDI Australia's promo ranges are Special Buys (Limited Time Only), Lower Prices and Super Savers. Adds the chosen range to the run alongside any search terms or categories. To scrape a specials listing in url mode instead, paste its ALDI listing URL. Leave as 'No specials filter' for a normal catalogue run.",
            "default": ""
          },
          "specialBuysDates": {
            "title": "Special Buys on-sale dates",
            "type": "array",
            "description": "Scrape the Special Buys that go on sale on these dates (search mode), e.g. '2026-10-08', '8 Oct' or 'Wed 8 October'. Enter 'all' for every date currently listed on ALDI's Special Buys page, or 'upcoming' for the dates from today onward. Each date is added to the run alongside any search terms or categories, and the Brands/Themes filters still apply. Leave empty to skip.",
            "items": {
              "type": "string"
            }
          },
          "excludeCategories": {
            "title": "Exclude departments",
            "type": "array",
            "description": "Department names to drop from the OUTPUT, e.g. 'Liquor', 'Limited Time Only', 'Front of Store'. Matched against each product's OWN reported department (its categoryPath), not just against what you listed in Categories/Specials; it also catches products that promo ranges like Lower Prices, Super Savers or The People's Picks cross-list from an excluded department. Leave empty to keep everything.",
            "items": {
              "type": "string"
            }
          },
          "brands": {
            "title": "Brands",
            "type": "array",
            "description": "Filter by brand name as shown on ALDI, e.g. 'EXPRESSI', 'URBAN EATS'. Leave empty for all brands. In url mode this is the fallback: a pasted URL's own 'brand-name' query param overrides it for that URL. Every run lists the brands ALDI offers for each search in the OUTPUT record (availableFilters).",
            "items": {
              "type": "string"
            }
          },
          "themes": {
            "title": "Themes",
            "type": "array",
            "description": "Filter by ALDI theme label, e.g. 'BBQ', 'Gardening', 'Pet Essentials', 'Christmas', 'Halloween', 'Liquor'. Leave empty for all. In url mode this is the fallback: a pasted URL's own 'theme' query param overrides it for that URL. Every run lists the themes ALDI offers for each search in the OUTPUT record (availableFilters), and Special Buys runs save the current themes per on-sale date in SPECIAL_BUYS_CALENDAR.",
            "items": {
              "type": "string"
            }
          },
          "sortBy": {
            "title": "Sort by",
            "enum": [
              "relevance",
              "price_asc",
              "price_desc",
              "name",
              "name_desc"
            ],
            "type": "string",
            "description": "Result ordering, applied by ALDI itself before Max products is reached, so 'Price: low to high' with Max products 20 returns ALDI's 20 cheapest matches. In url mode this is the fallback: a pasted URL's own 'sort' query param overrides it for that URL.",
            "default": "relevance"
          },
          "onSaleOnly": {
            "title": "On promotion only",
            "type": "boolean",
            "description": "Only return products that are on a promotion: a Special Buy (has an on-sale date), on a promotional range (Limited Time Only, Lower Prices or Super Savers), or showing a was-price. Applies in search mode and url mode. Products filtered out are not returned and not charged.",
            "default": false
          },
          "minPrice": {
            "title": "Minimum price (AUD)",
            "minimum": 0,
            "type": "number",
            "description": "Only return products priced at or above this amount, in Australian dollars. Applies in search mode and url mode. Products filtered out are not returned and not charged. Leave empty for no minimum."
          },
          "maxPrice": {
            "title": "Maximum price (AUD)",
            "minimum": 0,
            "type": "number",
            "description": "Only return products priced at or below this amount, in Australian dollars. Applies in search mode and url mode. Products filtered out are not returned and not charged. Leave empty for no maximum."
          },
          "urls": {
            "title": "URLs",
            "type": "array",
            "description": "ALDI URLs to scrape (url mode): product pages, category listings (incl. the bare /products page for the whole range), Special Buys on-sale-date pages (incl. the bare /special-buys landing page, which covers every date it currently lists), and search-result pages. Product URLs return a single detail record; every other shape returns its full result set (up to Max products). A pasted URL's own filter query params (brand-name, category-tree, theme, sort, page) are honoured straight off that URL and override the Brands/Themes/Sort by inputs above for that URL only; see the README for the full list of supported shapes.",
            "items": {
              "type": "string"
            }
          },
          "fetchDetails": {
            "title": "Fetch product details",
            "type": "boolean",
            "description": "Add full product-detail fields to every result: long description, ingredients, allergens, nutritional claims, usage and storage instructions, country of origin and the complete image gallery. Adds one request per product.",
            "default": false
          },
          "maxItems": {
            "title": "Max products",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum number of products to scrape across all terms/categories/URLs. Set 0 for unlimited.",
            "default": 20
          },
          "maxPages": {
            "title": "Max pages per term/category",
            "minimum": 0,
            "type": "integer",
            "description": "Optional safety cap on the number of result pages per search term or category (60 products per page). Leave empty for no page limit; the run stops at Max products."
          },
          "includeCategoryTree": {
            "title": "Save ALDI's category tree",
            "type": "boolean",
            "description": "Also save ALDI's full category tree (every department and aisle with its key, name, path, URL, parent and depth) to the run's key-value store as the record CATEGORY_TREE. Not added to the dataset and not charged. Off by default.",
            "default": false
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Proxy used for requests. Any Apify proxy works; the default is fine for most runs. Runs on any Apify plan."
          },
          "resumeFromRunId": {
            "title": "Resume from run/dataset (id)",
            "type": "string",
            "description": "Paste a previous run id from THIS actor to continue one interrupted crawl: this run skips every product id that run already collected, so a capped or aborted crawl can pick up where it left off without duplicate pushes/charges. A separate feature from Incremental mode below; see its description for when to use each. Leave empty for a normal run."
          },
          "incrementalMode": {
            "title": "Incremental mode (recurring monitoring)",
            "type": "boolean",
            "description": "For a search/category/URL set you run on a schedule (daily/weekly): the actor remembers its own baseline for this exact search and returns only NEW / UPDATED / REAPPEARED / EXPIRED products next time, instead of the full catalogue again. Unlike Resume from run/dataset above (which continues ONE specific interrupted run), this remembers the search itself across separate scheduled runs. Off by default so a normal run's output is unchanged.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional)",
            "type": "string",
            "description": "Only used with Incremental mode. Leave empty to key the baseline automatically off this run's search terms/categories/specials/brands/themes/sort/URLs/fetchDetails (two different searches never share state). Set your own text here to deliberately share one baseline across otherwise-different inputs, or to isolate multiple monitoring campaigns that would otherwise hash to the same key."
          },
          "emitUnchanged": {
            "title": "Emit unchanged products (Incremental mode)",
            "type": "boolean",
            "description": "Only used with Incremental mode. By default an UNCHANGED product (identical to last run) is NOT returned and NOT billed. Turn this on to also return every unchanged product every run; this returns and bills every tracked product, not just what changed.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired products (Incremental mode)",
            "type": "boolean",
            "description": "Only used with Incremental mode. When on, a product tracked by a previous run that no longer appears after a COMPLETE scan of this search is returned once with changeType EXPIRED, then dropped from the baseline. Skipped (with a log message) on a Max products-capped, resumed, or otherwise partial run, since an incomplete scan cannot tell 'gone' apart from 'not reached yet'. This returns and bills the expired rows in addition to NEW/UPDATED ones.",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Output field names that should NOT make a product count as UPDATED, even when they changed. Measured empty by default on this actor (a live re-fetch of the same products found no rotating/volatile field), so nothing is ignored unless you add one here. Matches a field name at any nesting depth (for example inside nutritionalInformation). Ignored fields are still returned in the output.",
            "items": {
              "type": "string"
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON; the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com)."
          },
          "notionParentPageUrl": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}