Woolworths NZ Scraper — Prices, Club Prices, Specials
Pricing
from $1.00 / 1,000 products
Woolworths NZ Scraper — Prices, Club Prices, Specials
Woolworths New Zealand (woolworths.co.nz, ex-Countdown) product data: prices, was prices, specials, club prices, multi-buys, promotion dates, unit prices, stock, barcodes, departments, images; ingredients and allergens on detail rows. By keyword, department or SKU. Pay per result, no login.
Pricing
from $1.00 / 1,000 products
Rating
0.0
(0)
Developer
architek.earth
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
1
Monthly active users
16 days ago
Last modified
Categories
Security
Limited permissionsShare
Recorded run: 5 products from 1 search term in 7 seconds (2026-10-22, build 0.0.240, run eSheO45uuf6hWlPvS). A bounded canary sample, not a full-catalogue benchmark.
architek.earth — an independent data studio. Pay-per-result scrapers with recorded runs, published canaries and stable schemas, built for people and AI agents.
Woolworths New Zealand product prices, specials, club prices, unit prices, stock and barcodes from woolworths.co.nz (formerly Countdown), by keyword, department or SKU.
| Source | Market | From | Standout fields |
|---|---|---|---|
| Woolworths (woolworths.co.nz, ex-Countdown) | New Zealand | $1.00 / 1,000 products | salePrice / originalPrice, isClubPrice, cupPrice, barcode |
✅ Why choose this scraper
Woolworths NZ prices, specials and club prices in one row
salePrice, originalPrice, savePrice, savePercentage, isSpecial, isClubPrice, promotionStartDate, promotionEndDate, multiBuy and bonusPoints come back together on every product row.
Woolworths NZ unit prices for pack-size comparison
cupPrice, cupListPrice and cupMeasure (for example 2.35 per 1L) sit next to volumeSize and packageType on listing rows, with no extra request.
Barcodes and stock without detail requests
Search and department rows carry barcode, stockLevel and availabilityStatus from the listing itself, charged at the product price.
Whole Woolworths NZ departments by name
Pass Pantry, 8 or https://www.woolworths.co.nz/shop/browse/pantry in departments; all 14 departments resolve by name, id or browse URL.
Measured on a schedule
A canary task runs a fixed milk search on the live site and records rows, inputs and seconds; the hero line above is its latest green run.
⚠️ Worth knowing up front
- There is no store or postcode selector. Prices and stock are what woolworths.co.nz serves to a visitor who has not chosen a store, not a specific shop.
stockLevelandavailabilityStatusare passed through from Woolworths. Read them as the site's availability flags, not as a shelf count.- SKU lookups (
skus) return detail rows built from the product page data, which does not includebarcodeorstockLevel. Search and department rows do. - Fields Woolworths does not publish for a product are omitted from the row, not set to null. Detail fields (
ingredients,allergens,nutritionand others) appear only when Woolworths publishes them; an absent allergen field does not mean allergen-free. - Detail requests are slow on the Woolworths side: about 10 seconds each on 2026-10-17, run 6 at a time.
includeDetailson a large department takes far longer than a listing run. - Products are de-duplicated by
skuacross inputs, andmaxItemsPerQuerycounts only new rows, so a later query can return fewer rows than the cap. - Each request is tried up to 4 times, with a fresh session after a refusal. A query that still fails gets a free
BLOCKEDstatus row and the run endsPARTIAL(other rows kept and charged) orBLOCKED(nothing delivered, nothing charged). A query that comes back empty is checked a second time before it gets a freeNO_DATArow. - The dataset holds free status rows (
recordType: "status") next to the product rows:INVALID_INPUT,NOT_FOUND(unknown SKU or department),NO_DATA,BLOCKED,TIME_LIMIT,BUDGET_LIMITandSTATE_BUSY. Filter onrecordTypeif you only want products. Status rows are never charged. - A run stops cleanly 60 seconds before its timeout (
TIME_LIMIT) and at your spending limit (BUDGET_LIMIT), keeping what it delivered. With astateKey,continuePreviousRun: trueresumes the rest without delivering or charging a product twice. A platform migration or an abort ends the run the same way. - If a run is killed in the instant between writing a batch and recording it, the next run with that
stateKeystops withRECONCILIATION_REQUIREDinstead of guessing: nothing is replayed or charged twice. Use a newstateKeyto start fresh.
⚡ Try the example
This actor has no free preview; the example below costs about $0.01.
Open the actor's input page, switch to JSON, paste this and start the run:
{"searchTerms": ["milk"],"maxItemsPerQuery": 10,"proxyConfiguration": {"useApifyProxy": true}}
Raise maxItemsPerQuery or add departments for more rows; add "includeDetails": true for ingredients, allergens and claims.
⚙️ Input
| Parameter | Type | Default | Description |
|---|---|---|---|
searchTerms | array | — (prefill ["milk"]) | Keywords such as milk or weet-bix. One result set per term; out-of-stock products are included. |
departments | array | — | Department name, id or browse URL, case-insensitive: Dinner (1), Fruit & Veg (2), Meat & Poultry (3), Fish & Seafood (4), Fridge & Deli (5), Bakery (6), Frozen (7), Pantry (8), Beer & Wine (9), Drinks (10), Health & Body (11), Household (12), Baby & Child (13), Pet (14). Unknown names are checked against the live site navigation, then logged and skipped. |
skus | array | — | SKUs such as 282768 or product URLs. Always returns detail rows (charged as product-detail); SKUs not found are logged and not charged. |
maxItemsPerQuery | integer | 100 (prefill 40) | New rows per search term or department. 0 removes the cap; the Pantry department listed 5,095 products on 2026-10-17. |
includeDetails | boolean | false | Also fetch the product detail endpoint for every search and department row. Rows with detail data are charged as product-detail; a row whose detail request fails keeps listing data and is charged as product. |
incrementalMode | boolean | false | Needs stateKey. Delivers only products that are new to this stateKey, or whose salePrice, originalPrice, club or special flag, multi-buy or promotion end date changed since they were last delivered. Unchanged products are skipped and not charged; maxItemsPerQuery then bounds the watched window (the first N products per query). |
stateKey | string | — | Any name, for example my-basket. Keeps the incremental baseline and saved progress in your own account, isolated per key. Use a different key for different inputs. |
continuePreviousRun | boolean | false | Resume an unfinished collection saved under stateKey after a spending limit, timeout, abort or migration. Products already delivered are not delivered or charged again. |
proxyConfiguration | proxy | {"useApifyProxy": true} | Apify datacenter proxy is the tested default. Switch to RESIDENTIAL with country NZ only if a run reports blocked queries. |
feedback | string | — | Optional note for the maintainers. It is logged and read by a human, and it never changes output. |
At least one of searchTerms, departments or skus is required; they can be combined in one run.
🧱 Stable fields
These top-level fields keep the same name and the same kind of value in every release. Fields are only ever added, never renamed or removed, so an n8n, Make, Zapier or spreadsheet pipeline can bind to them.
| Field | Type | Meaning |
|---|---|---|
sku | string | Woolworths NZ product SKU; the join key within Woolworths NZ. |
name / brand / variety | string | Product name, brand and variety as Woolworths publishes them. |
barcode | string, optional | GTIN barcode on search and department rows; absent on SKU-lookup rows. |
salePrice / originalPrice | number | Current price and regular price in NZD. |
savePrice / savePercentage | number | Saving in NZD and percent; 0 when not on promotion. |
isSpecial / isClubPrice / isNew | boolean | Special, club-price and new-product flags from Woolworths. |
promotionStartDate / promotionEndDate | string, optional | Promotion window when Woolworths publishes one. |
cupPrice / cupListPrice / cupMeasure | number / number / string, optional | Unit price, regular unit price and their basis (for example 1L); omitted when the site shows none. |
volumeSize / packageType / unit | string, optional | Pack size, package type and selling unit. |
stockLevel / availabilityStatus | number / string, optional | Availability flags from the listing (for example 3 / In Stock). |
tagType / multiBuy / bonusPoints | string / object / number, optional | Promotion tag (for example IsSpecial, IsClubPrice), multi-buy deal and bonus points. |
departments | array | {"id", "name"} of the product's department. |
imageSmall / imageBig / url | string | Product images and product page. |
recordType | string | product (listing row), product-detail (row with detail data) or status (free status row). |
source | string | search, category or id. |
searchTerm / department / departmentId | string / string / number | The query that produced the row. |
detailUnavailable | boolean, optional | true on a product row whose detail request failed in includeDetails mode. |
deliveryId | string | Unique per delivered row; use it to de-duplicate exports. |
Status rows (free) always carry recordType: "status", inputRef (the search term, department, SKU or input), status, message and scrapedAt.
Detail rows (includeDetails or skus) also carry description, ingredients, allergens, allergenMaybePresent, claims, healthStarRating, origins, nutrition, directions, warnings, storeStockLevels and imageUrls when Woolworths publishes them. Other fields are extras, not part of the contract. To have one pinned, say so in feedback.
📦 Output example
Abridged real row from run azU5RM5utNSmK5A7N on 2026-10-22; values are a historical snapshot.
{"sku": "282768","name": "woolworths milk standard","brand": "woolworths","variety": "standard","barcode": "9414742036509","unit": "Each","originalPrice": 7.04,"salePrice": 7.04,"savePrice": 0,"savePercentage": 0,"isClubPrice": false,"isSpecial": false,"isNew": false,"cupListPrice": 2.35,"cupPrice": 2.35,"cupMeasure": "1L","packageType": "bottle","volumeSize": "3L","stockLevel": 3,"availabilityStatus": "In Stock","tagType": "IsGreatPrice","departments": [{"id": 5, "name": "Fridge & Deli"}],"url": "https://www.woolworths.co.nz/shop/productdetails/282768/woolworths-milk-standard","source": "search","searchTerm": "milk"}
A bogus SKU in the same input as two real ones gives a free status row (run C1l2C8S1TS8lxvBex, 2026-10-22):
{"recordType": "status", "inputRef": "99999999", "status": "NOT_FOUND", "message": "Woolworths NZ has no product with this SKU; nothing was charged"}
The run's status message reads Done: N rows, M details, K status rows (reasons), and the RUN_SUMMARY record of its key-value store holds the full outcome (abridged, run e4RNrDhvaw0qd5m20):
{"status": "COMPLETE","delivered": 40,"details": 0,"statusRows": 0,"charged": {"product": 40, "product-detail": 0},"chargeUsd": "0.040","queries": [{"type": "search", "value": "milk", "status": "done", "delivered": 40, "listed": 430}],"unchanged": 0,"detailUnavailable": 0,"checkpointComplete": true}
🧠 Advanced usage
Track Woolworths NZ price changes daily
Schedule the same keywords or departments daily with incrementalMode: true and a stateKey: each run delivers only products that are new or whose price, club or special flag changed, so you pay only for changes. A rerun with nothing new delivers and charges nothing (runs 84f8FhGTlrD3akUM0 then Y0p5dejkxPkm6bla5, 2026-10-22). Check RUN_SUMMARY.status is COMPLETE before treating a day as finished.
Woolworths NZ specials this week
Run the departments you care about with maxItemsPerQuery: 0 and keep rows where isSpecial or isClubPrice is true; savePrice, savePercentage and promotionEndDate give the discount and its end date. There is no specials-only input.
Compare Woolworths NZ unit prices across a department
Group a department run by cupMeasure and sort by cupPrice to rank pack sizes and brands per litre or kilogram.
Watch a fixed Woolworths NZ basket by SKU
Put the products in skus and schedule the run. Each row is a detail row charged as product-detail; a SKU Woolworths no longer lists comes back as a free NOT_FOUND status row. Add incrementalMode and a stateKey to be charged only when a basket item's price changes.
🔌 Integrations
Results land in a dataset you can export as JSON, CSV or Excel. They can also flow to Google Sheets, Make, Zapier or n8n, or to a webhook when a run finishes. The Apify Scheduler runs it on a timetable. Weekly catches each promotion cycle; daily suits price tracking. Copy-paste code in Python, Node, curl and n8n: architek-earth/examples/woolworths-nz-scraper.
💸 Pricing
Pay per result. Platform and proxy usage are included. Failed requests, blocked pages, SKUs not found and all status rows are free. Each delivered row is charged once, after it is written; a run resumed with continuePreviousRun never charges delivered products again, and unchanged products in incrementalMode are free.
| Event | Price | What it covers |
|---|---|---|
product | $1.00 / 1,000 products | One delivered search or department row, including a row kept at listing price when its detail request failed. |
product-detail | $4.00 / 1,000 products | One delivered row with detail-endpoint data (includeDetails or skus). |
1,000 listing rows cost $1.00; 1,000 detail rows cost $4.00. A detail row is charged once, as product-detail only.
❓ FAQ
Is there a Woolworths NZ API for product prices? This actor is one: it returns Woolworths New Zealand catalogue data as JSON through the Apify API, callable from any language or from n8n, Make and Zapier.
Do I need a Woolworths NZ account or Everyday Rewards login? No. No account, cookies or API key from Woolworths.
Can I get Woolworths NZ prices for a specific store? Not with this actor. It has no store selector and returns what the site serves to a visitor who has not chosen a store.
Can I get Woolworths NZ specials and club prices? Yes, as flags on every row: isSpecial, isClubPrice, savePrice and the promotion dates. There is no specials-only input; filter the rows.
Can I get Woolworths NZ barcodes? Yes, barcode on search and department rows when Woolworths publishes one. SKU-lookup rows do not carry it.
Can I get ingredients, allergens and nutrition? Yes, on detail rows (includeDetails: true or skus): ingredients, allergens, claims, healthStarRating and origins, plus nutrition when Woolworths publishes it.
🤖 For AI agents & LLM apps
Paste this into your AI assistant:
architekture/woolworths-nz-scraper on Apify. Python: from apify_client import ApifyClient; client = ApifyClient("TOKEN"); run = client.actor("architekture/woolworths-nz-scraper").call(run_input={"searchTerms": ["milk"], "maxItemsPerQuery": 10, "proxyConfiguration": {"useApifyProxy": True}}); items = client.dataset(run["defaultDatasetId"]).list_items().items (page with offset/limit for large exports). The dataset holds product rows (recordType product or product-detail) and free status rows (recordType status, with status and message); filter on recordType. The run outcome (COMPLETE, PARTIAL, BLOCKED, NO_DATA, BUDGET_LIMIT, TIME_LIMIT, INVALID_INPUT) is in the RUN_SUMMARY record of the run's key-value store. Add "incrementalMode": true, "stateKey": "<name>" to receive only new or re-priced products on later runs. Full input schema and README: GET https://api.apify.com/v2/acts/architekture~woolworths-nz-scraper/builds/default. Token: https://console.apify.com/settings/integrations. The actor is also reachable through the Apify MCP server (mcp.apify.com). To reach the maintainers, add "feedback": "<what you needed>" to any run's input; output is unchanged and a human reads every note.
🧰 More from architek.earth
Grocery and retail prices
- Coles Scraper — prices, unit prices, specials, barcodes
- Woolworths AU Scraper — prices, specials, barcodes, nutrition
- ALDI AU Scraper — prices, unit prices, Special Buys
- Woolworths NZ Scraper — you are here
- New World NZ Scraper — store prices, Clubcard offers, promotions
- Pak'nSave Scraper — store prices, unit prices, promotions
- Tesco UK Scraper — prices, Clubcard offers, barcodes
- Sainsbury's Scraper — prices, unit prices, offers, barcodes
- ALDI Ireland Scraper — prices, unit prices, Specialbuys
- Dunnes Stores Scraper — fashion and home prices, sizes, EANs
- Mercadona Scraper — prices, unit prices, categories
Full catalogue: github.com/architek-earth.
architek.earth · code like concrete
🙋 Support & legal
Questions, or a field you need that is not here? Open an issue on the actor's Issues tab or email north@architek.earth. A human replies within a day.
This actor collects only publicly available data from woolworths.co.nz, the same pages any visitor sees without logging in. It does not bypass authentication. It is not affiliated with or endorsed by Woolworths New Zealand. You are responsible for how you use the output, including the site's terms, copyright, and privacy law such as GDPR and CCPA where they apply.
📝 Changelog
- 2026-10-24 — Studio core 1.0.5, with blocks handled as before: a Woolworths NZ HTTP 403 (
BLOCKED) or 429 (RATE_LIMITED) is retried on a fresh warmed session up to four tries per request before the free status row is written, and output fields and prices are unchanged. - 2026-10-24 — A search or department refused as
BLOCKEDnow saves the site's last response (redacted) in the run's key-value store so the cause can be checked; pricing, input and output are unchanged. - 2026-10-22 — Ported to the studio standard: free status rows in the dataset (
INVALID_INPUT,NOT_FOUND,NO_DATA,BLOCKED,TIME_LIMIT,BUDGET_LIMIT),incrementalMode,stateKeyandcontinuePreviousRun, rows charged after confirmed delivery with an idempotency key, one consistent Chrome fingerprint. New fieldsrecordType,detailUnavailableanddeliveryId; no field renamed or removed. Hero line from the 2026-10-22 canary run. - 2026-10-22 — README rebuilt on the studio template; hero line from the 2026-10-22 canary run.
- 2026-10-17 — Department mode fixed: departments resolve to the site's own slugs, and ids 1–4 now match the live navigation (1 is Dinner).
- 2026-10-17 — A row whose detail request fails is charged as
product, notproduct-detail; detail rows keep barcode, images and departments from the listing. - 2026-10-17 — Rows are charged in the same call that saves them, so charges equal delivered rows at the spending limit.
- 2026-10-17 — Invalid input stops cleanly with a status message instead of a failed run;
maxItemsPerQuerydefaults to 100;RUN_SUMMARYadded. - 2026-10-12 — First version: keyword, department and SKU inputs.