# New World NZ Scraper — Store Prices, Clubcard, Specials (`architekture/new-world-nz-scraper`) Actor

Compare New World New Zealand product prices by store: shelf prices, Clubcard offers, unit prices and promotions. Optional details add published barcodes and nutrition. No supermarket login. US$4/1,000 product rows plus US$0.15 per run that delivers products.

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

## Pricing

from $4.00 / 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

## New World NZ Scraper — Store Prices, Clubcard, Specials

**Recorded 17 Oct 2026: the same products priced at four New World stores (Wellington, Auckland, Queenstown) — 38 of the 39 products stocked by all four had a different price somewhere. A 750 g Weet-Bix was $6.99 at Thorndon and Queenstown and $7.89 at Metro Willis St.**

From **Architekture**, makers of the Pak'nSave NZ, Woolworths NZ, Woolworths AU, Coles AU, ALDI AU, Tesco UK and Sainsbury's UK scrapers.

New World stores are individually owned and set their own prices. This actor returns New World products **store by store**: shelf price, Clubcard price, unit price, promotions, category and link, for one store, a handful, or all of them (about 150 online stores). Search by keyword or browse whole categories. Optional product details add the barcode (EAN), ingredients, allergens, nutrition and image. No New World account needed.

### Why choose this actor

- **Prices for the store you name.** Every row carries `storeId`, `storeName` and `storeRegion`; ask for `["Thorndon", "Queenstown"]` and you get each store's own `price` side by side. `"all"` covers every online New World store.
- **Clubcard price, separately.** `price` is the shelf price; `clubPrice` (and `clubPricePerUnit`) appears when the product has a Clubcard-only price at that store. Multi-buys stay in `promotions` — never passed off as a single-item price.
- **Unit pricing as New World shows it.** `pricePerUnit` with `pricePerUnitLabel` (e.g. `1L`, `1kg`) for like-for-like comparison.
- **Barcodes for joins.** With `includeDetails: true`, `barcode` (EAN-13) lets you join New World against Pak'nSave, Woolworths NZ or your own catalogue.
- **Clean stops and fair billing.** A run that finds nothing costs nothing; hitting your spending limit or the run timeout ends with a summary and everything collected so far.

### Worth knowing up front

- **New World is behind Cloudflare.** Each run starts a real browser on a New Zealand residential IP to get an anonymous shop session (about 15–25 seconds), then reads New World's own product API. That warm-up is why there is a per-run fee (below). Residential NZ proxy is required and is the default.
- **Prices are online-shop prices for the chosen store.** They match what newworld.co.nz shows for that store; in-store shelf tickets can differ on the day.
- **No stock levels.** New World publishes which channels sell a product (`availabilityChannels`: `IN_STORE`, `ONLINE`), not how many are on the shelf. Nobody can return stock counts from the public site.
- **Search depth:** 50 products per page, at most 1,000 per search per store (New World's search limit).
- **No account features.** No order history, no personalised prices, no "bought before" flags — this actor never logs in.

### Try the example

```json
{
  "searchTerms": ["milk"],
  "stores": ["New World Thorndon", "New World Queenstown"],
  "maxItemsPerQuery": 20
}
```

40 rows (20 per store) in about a minute: $0.15 run fee + 40 × $0.004 = $0.31.

### Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `searchTerms` | array of strings | — | Keywords, up to 50 per run. |
| `categories` | array of strings | — | Category name (`Pantry`), path (`pantry/baking-supplies-and-sugar`) or URL (`https://www.newworld.co.nz/shop/category/pantry`). Matched against each store's own category tree. |
| `stores` | array of strings | `["New World Thorndon"]` | Store names (the "New World" part is optional), store ids, or `"all"`. A name that matches several stores (e.g. `Metro`) is rejected with the matches listed. |
| `maxItemsPerQuery` | integer | `100` | Products per search (or category) per store. `0` = everything listed, up to 1,000. |
| `includeDetails` | boolean | `false` | Adds `barcode`, `description`, `ingredients`, `allergens`, `nutrition`, `imageUrl`. One extra request per product: slower, same price per product. |
| `proxyConfiguration` | object | RESIDENTIAL, NZ | Leave as is; other proxies are not tested. |
| `feedback` | string | — | A note to the maintainers. Read by a human; does not change output. |

Use `searchTerms`, `categories`, or both. Each store × search pair is one search; a run takes up to 600.

### Stable fields for automations

These keep their names and meaning across versions; new fields are only added. A field is **omitted** (not `null`) when New World does not publish it for that product.

| Field | Meaning |
|---|---|
| `id` | New World product id, e.g. `5201479-EA-000`. Unique per store per run. |
| `name` | Product name. |
| `brand` | Brand. |
| `packageSize` | Size as shown, e.g. `2l`, `500g`. |
| `price` | Shelf (non-Clubcard) price at this store, NZD. |
| `clubPrice` | Clubcard-only single-item price at this store, NZD, when there is one. |
| `clubPricePerUnit` | Unit price at the Clubcard price. |
| `pricePerUnit` | Unit price at the shelf price, NZD. |
| `pricePerUnitLabel` | Unit for `pricePerUnit`, e.g. `1L`, `1kg`. |
| `isOnPromotion` | `true` when New World lists any promotion for it at this store. |
| `promotions` | Offers as published: `type`, `value` (NZD), `quantity` (2 = "2 for"), `clubcardOnly`. |
| `saleType` | How New World sells it, e.g. `UNITS` (per item). |
| `availabilityChannels` | `IN_STORE` / `ONLINE`. Channels, not stock. |
| `category` | `Department > Aisle > Shelf`, e.g. `Fridge, Deli & Eggs > Milk > Fresh Milk`. |
| `isLiquor`, `isRestricted` | Age-restricted product flags. |
| `url` | Product page on newworld.co.nz. |
| `storeId`, `storeName`, `storeRegion` | The store these prices belong to. |
| `position` | Rank in that store's results (1 = first). |
| `source` | `{source: "search", query, page}` or `{source: "category", category, page}`. |
| `barcode`, `description`, `ingredients`, `allergens`, `nutrition`, `imageUrl` | With `includeDetails` only. |

### Output example

```json
{
  "id": "5227964-EA-000",
  "name": "Protein Fix Iced Chocolate Flavoured Milk",
  "brand": "Mammoth Supply Co.",
  "packageSize": "600ml",
  "price": 5.99,
  "pricePerUnit": 9.98,
  "pricePerUnitLabel": "1L",
  "clubPrice": 5.49,
  "clubPricePerUnit": 9.15,
  "isOnPromotion": true,
  "promotions": [{ "promoId": "130442327", "type": "NEW_PRICE", "value": 5.49, "quantity": 1, "clubcardOnly": true }],
  "saleType": "UNITS",
  "availabilityChannels": ["IN_STORE", "ONLINE"],
  "category": "Hot & Cold Drinks > Hot Chocolate & Milk Drinks > Flavoured Milk",
  "isLiquor": false,
  "isRestricted": false,
  "url": "https://www.newworld.co.nz/shop/product/5227964_ea_000nw",
  "storeId": "38b074c4-0e5a-4bd5-b743-d30f28d94982",
  "storeName": "New World Metro Willis St",
  "storeRegion": "Wellington",
  "position": 38,
  "source": { "source": "search", "query": "milk", "page": 1 }
}
```

### Advanced usage

- **Price map across stores:** `stores: ["all"]`, a short `searchTerms` list, `maxItemsPerQuery: 50`; pivot on `id` × `storeName`.
- **Clubcard savings:** keep rows with `clubPrice`; `price - clubPrice` is the member saving at that store.
- **Cross-retailer basket:** run with `includeDetails: true`, then join on `barcode` with our Pak'nSave NZ and Woolworths NZ actors.
- **Daily monitoring:** schedule the same stores and terms; compare `price`/`clubPrice` per `storeId` + `id` day to day.
- **Completion check:** read `RUN_SUMMARY` — `status` (`COMPLETE`, `PARTIAL`, `BLOCKED`, `BUDGET_LIMIT`, `TIME_LIMIT`, `INVALID_INPUT`), `products`, `runFeeCharged`, and `searches` (per store × query: `status`, `delivered`, `listed`, `pagesRead`).

### Integrations

Export as JSON, CSV, Excel or RSS; push to Google Sheets; trigger from Make, Zapier or n8n; webhook on run finish; schedule with the Apify Scheduler.

### Pricing

| Event | Price | Covers |
|---|---|---|
| `collection-delivered` | $0.15 per run | Once per run, only after the first product is saved. Covers the browser warm-up past Cloudflare. |
| `product` | $4.00 / 1,000 | One product row (one product at one store) delivered to the dataset. |

Platform usage and the residential proxy are included. A run that delivers nothing is not charged at all, and nothing is charged for failed requests or for products the run could not save. Set a maximum charge of at least $0.154 (one fee + one product); lower limits are rejected before the run starts. Examples: 100 products = $0.55; 1,000 = $4.15; 10,000 in one run = $40.15.

### FAQ

**Do prices really differ between New World stores?** Yes. In our 17 Oct 2026 check, 38 of 39 products stocked by four stores had a different price at one or more of them. Two stores can still share prices for many products (two Metro stores matched on every product we checked), so compare the stores you care about.

**Is `price` the Clubcard price?** No. `price` is the price without a Clubcard; `clubPrice` is the Clubcard-only price when there is one.

**Can I get stock levels?** No. New World does not publish them; `availabilityChannels` only says whether a product is sold in store and/or online.

**Why a per-run fee?** Every run has to start a real browser to get past Cloudflare before it can read a single product. The fee covers that; it is charged once and only when the run delivers products.

**How do I find a store's id?** Use its name (`"Thorndon"`), or run once with any store and read `stores` in `RUN_SUMMARY`; ids are listed there.

**Why did my run end `BLOCKED`?** New World did not issue a shop session after several fresh browsers and IPs. Nothing was charged; rerun later. If it repeats, open an issue — we are alerted on consecutive failures too.

**Do I need a New World account?** No, and the actor never uses one.

**How fast?** Measured on live validation runs (2026-10-17): ~10 s browser warm-up, then ~12 products/s sustained — a 2,000-product category run finished in 122 s, and 4,100+ products in under 6 minutes. With `includeDetails` add a fraction of a second per product.

### For AI agents & LLM apps

`architekture/new-world-nz-scraper` returns New World New Zealand products with each store's own prices — shelf `price`, `clubPrice`, unit price, promotions, category, product URL, and the store they belong to — as deterministic, schema-stable JSON, one object per product per store, same fields on every run, so agents and RAG pipelines can parse it without defensive code. Invoke it from any agentic workflow via the Apify API or the Apify MCP server (`mcp.apify.com`) as a tool call; pay-per-event billing means a run costs a known amount before it starts ($0.15 per productive run + $4 per 1,000 products; `maxItemsPerQuery` caps it). Each run writes a `RUN_SUMMARY` record with a machine-readable `status` and per-store, per-search outcome, so an agent can branch on `BLOCKED` or `BUDGET_LIMIT` instead of parsing logs. Honest limits: no stock levels, no account-only data, online-shop prices for the store requested.

### More Architekture scrapers

- **NZ grocery:** New World NZ (you are here) · [Pak'nSave NZ](https://apify.com/architekture/paknsave-nz-scraper) · [Woolworths NZ](https://apify.com/architekture/woolworths-nz-scraper)
- **AU grocery:** [Woolworths AU](https://apify.com/architekture/woolworths-au-product-scraper) · [Coles AU](https://apify.com/architekture/coles-au-product-scraper) · [ALDI AU](https://apify.com/architekture/aldi-au-product-scraper)
- **UK grocery:** [Tesco UK](https://apify.com/architekture/tesco-uk-scraper) · [Sainsbury's UK](https://apify.com/architekture/sainsburys-uk-scraper)
- **E-commerce:** [AliExpress Search](https://apify.com/architekture/aliexpress-search-scraper)

New World and Pak'nSave run on the same Foodstuffs platform, so their field names match (`id`, `price`, `pricePerUnit`, `storeId`, `promotions`); other retailers' fields are similar but not identical.

### Support

Open an Issue on this actor's page; a human replies within a day.

### Legal compliance

This actor reads publicly available product and price pages, without logging in. You are responsible for how you use the data, including New World's terms of use, intellectual property in product names and images, and data-protection law where it applies.

### Changelog

- **2026-10-17** — 1.0: keyword search and category browsing; store-by-store prices for one, several or all New World stores; Clubcard price, unit price and promotions; optional barcode, ingredients, allergens, nutrition and image; de-duplication per store; clean stops at spending limit and timeout; resumable after platform migration.

# Actor input Schema

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

Product keywords, searched the way a shopper types them on newworld.co.nz (e.g. milk, weet-bix). Up to 50.

## `categories` (type: `array`):

Browse whole categories instead of (or as well as) searching: a category name ("Pantry"), a path ("pantry/baking") or a category URL (https://www.newworld.co.nz/shop/category/pantry). Matched against each store's own category tree.

## `stores` (type: `array`):

New World stores to price, by name ("Thorndon", "New World Queenstown") or store id. Prices differ between stores, so every product row carries its store. Use "all" for every online store (about 150). Default: New World Thorndon.

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

Stop each search term or category at each store after this many products. 0 = everything New World lists (at most 1,000 per search per store).

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

Also fetch each product's detail record: barcode (EAN), description, ingredients, allergens, nutrition and image. One extra request per product, so slower; same price per product.

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

New World is protected by Cloudflare: Apify RESIDENTIAL proxy in New Zealand is required and is the tested default.

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

Tell the maintainers what you needed and did not get. Read by a human; does not change the output.

## Actor input object example

```json
{
  "searchTerms": [
    "milk"
  ],
  "stores": [
    "New World Thorndon",
    "New World Queenstown"
  ],
  "maxItemsPerQuery": 20,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "NZ"
  }
}
```

# Actor output Schema

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

One row per product per store in the default dataset.

## `summary` (type: `string`):

RUN_SUMMARY record: status, per-store/per-search counts, charges.

# 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"
    ],
    "stores": [
        "New World Thorndon",
        "New World Queenstown"
    ],
    "maxItemsPerQuery": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "NZ"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("architekture/new-world-nz-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"],
    "stores": [
        "New World Thorndon",
        "New World Queenstown",
    ],
    "maxItemsPerQuery": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "NZ",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("architekture/new-world-nz-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"
  ],
  "stores": [
    "New World Thorndon",
    "New World Queenstown"
  ],
  "maxItemsPerQuery": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "NZ"
  }
}' |
apify call architekture/new-world-nz-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,architekture/new-world-nz-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/yyFww0tYtShBojVPe/builds/IDxWsUSYw9v9E21ce/openapi.json
