Pak'nSave Scraper — Store Prices, Unit Prices, Promotions
Pricing
from $4.00 / 1,000 products
Pak'nSave Scraper — Store Prices, Unit Prices, Promotions
Pak'nSave New Zealand (paknsave.co.nz) scraper: product ID, name, brand, package size, price in NZD, unit price, unit label, promotions, category, sales channels, URL, store ID. Per store, by keyword or Pantry category, with continuation. Pay per result, no login.
Pricing
from $4.00 / 1,000 products
Rating
0.0
(0)
Developer
architek.earth
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
2
Monthly active users
16 days ago
Last modified
Categories
Security
Limited permissionsShare
Recorded run: 5 products from 1 search term in 54 seconds (2026-10-22, build 0.0.23, run GMpvgGaa8OdRkLf3k). 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.
Pak'nSave NZ product prices, unit prices and promotions from paknsave.co.nz for one chosen store, by keyword or the Pantry category.
| Source | Market | From | Standout fields |
|---|---|---|---|
| Pak'nSave (paknsave.co.nz) | New Zealand | $4.00 / 1,000 products | price, pricePerUnit, storeId, promotions |
✅ Why choose this scraper
Pak'nSave prices for a chosen store
Every row carries the storeId you requested (a public Pak'nSave store UUID); blank input selects Royal Oak. Prices are numeric NZD in price, converted from the source's cents.
Pak'nSave unit prices for pack-size comparison
pricePerUnit and pricePerUnitLabel (for example 5.11 per "1L") come back next to packageSize, with no currency strings to parse.
Pak'nSave promotions as the source publishes them
When a product has offers, promotions holds the source list unchanged; multi-buy rewards are never written into price.
A run status you can check
The SUMMARY record says complete, limited, partial or failed, with rows delivered this run; products are de-duplicated by id across queries and continuations.
Measured on a schedule
A canary task runs a fixed milk search at the default store on the live site and records rows, inputs and seconds; the hero line above is its latest green run.
⚠️ Worth knowing up front
- Prices are store-scoped. Assortments were verified to differ between stores; overlapping sampled prices were identical, so price differences between stores have not been demonstrated.
storeIdrecords the requested store; the response does not echo it. - Every run needs a browser warm-up and an Apify residential proxy in New Zealand before product requests. Other proxy settings are rejected. The warm-up is why paid runs carry a $0.15 collection fee.
- Keyword search and the Pantry category (
https://www.paknsave.co.nz/shop/category/pantry) are supported. Other category URLs are rejected before collection. Some searches stop at a 1,000-result source ceiling. - Not returned: ingredients, nutrition, barcodes, image URLs, stock quantities, membership prices or separate was-prices.
availabilityis always"unknown";availabilityChannels(IN_STORE,ONLINE) are sales channels, not stock.includeDetails: trueis rejected. promotionsis optional source passthrough, not part of the stable contract. ObservedrewardValuevalues are in cents, and multi-buy quantities and conditions apply.- A run stopped by its time bound or spending limit keeps what it delivered and saves
CHECKPOINT;SUMMARYthen sayslimitedorpartial. That is a partial collection, not a full catalogue. - A run that stops early ends with a free status row (
"recordType": "status") that says why. CheckRUN_SUMMARYfor the outcome of every run.
⚡ Try the example
Each Apify account gets 20 lifetime free preview attempts on this actor: one page, up to 10 rows across the whole run, no charges. Failed or uncertain reservations can consume an attempt. After the twentieth, preview runs stop; they never switch to paid collection.
Open the actor's input page, switch to JSON, paste this and start the run:
{"operation": "collect","searchTerms": ["milk"],"storeId": "e1925ea7-01bc-4358-ae7c-c6502da5ab12","preview": true,"maxItemsPerQuery": 10,"maxRunSeconds": 60}
For paid collection set "preview": false and a spending limit of at least $0.154; 10 paid products cost $0.19.
⚙️ Input
| Parameter | Type | Default | Description |
|---|---|---|---|
operation | select | collect | Use collect. capture is a developer diagnostic and is rejected on public runs. |
searchTerms | array | ["milk"] | Product keywords, up to 100. Set to [] for category-only collection. |
categoryUrls | array | [] | Only https://www.paknsave.co.nz/shop/category/pantry is supported; other categories are rejected before collection. |
storeId | string | — (Royal Oak) | Public Pak'nSave store UUID. Blank selects Royal Oak (e1925ea7-01bc-4358-ae7c-c6502da5ab12). A malformed ID returns a free INVALID_INPUT row. |
maxItemsPerQuery | integer | 100 | Cap per search term or category across a continuation chain, 0 to 100,000. 0 removes the item cap, not time or spending limits. |
preview | boolean | true | Free preview: one of 20 lifetime attempts, one page, up to 10 rows. false enables paid collection. |
includeDetails | boolean | false | Leave false. true is rejected; no detail fields are available. |
continuePreviousRun | boolean | false | Paid only. Claims a saved checkpoint once. |
previousStoreId | string | — | The previous run's default key-value store ID (holds CHECKPOINT and CHECKPOINT_META), not a retailer store ID. |
previousQueueId | string | — | queueId from the previous run's CHECKPOINT_META; prevents the same checkpoint being replayed. |
maxRunSeconds | integer | 240 | Collection deadline including warm-up, 60 to 3,600 seconds; clamped to the platform timeout. |
proxyConfiguration | proxy | Residential, NZ | Must be Apify residential proxy with NZ egress. Included in the price. |
debugSaveResponses | boolean | false | Saves the last source response, with secrets redacted, as DEBUG-LAST-RESPONSE. Review before sharing. |
captureCostMode | select | none | Developer-only. Leave at none. |
feedback | string | — | Optional note for the maintainers. It is logged and read by a human, and it never changes output. |
🧱 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 |
|---|---|---|
id | string | Pak'nSave product ID (for example 5007415-EA-000); the de-duplication key within this actor. |
name | string | Product name. |
url | string | Product page on paknsave.co.nz. |
storeId | string | The requested store UUID. |
source | object | {"source": "search", "searchTerm": …} or {"source": "category", "categoryUrl": …}. |
availability | string | Always "unknown"; no stock inference. |
brand | string, optional | Brand, when supplied. |
packageSize | string, optional | Source pack-size label, for example 1l. |
price | number, optional | Individual product price in NZD. |
pricePerUnit | number, optional | Unit price in NZD. |
pricePerUnitLabel | string, optional | Unit basis, for example 1L. |
category | string, optional | First source category path, for example Fridge, Deli & Eggs > Milk > Fresh Milk. |
availabilityChannels | array, optional | Source sales channels such as IN_STORE and ONLINE; not stock quantities. |
recordType | string | "status" on free status rows; absent on product rows. |
Optional fields are omitted when the source does not supply them, never invented. promotions is an extra, not part of the contract. To have one pinned, say so in feedback.
📦 Output example
Abridged real row from run GMpvgGaa8OdRkLf3k on 2026-10-22; values are a historical snapshot.
{"id": "5007415-EA-000","name": "Zero Lacto Blue Milk","url": "https://www.paknsave.co.nz/shop/product/5007415_ea_000pns","storeId": "e1925ea7-01bc-4358-ae7c-c6502da5ab12","source": {"source": "search", "searchTerm": "milk"},"availability": "unknown","brand": "Anchor","packageSize": "1l","price": 5.11,"pricePerUnit": 5.11,"pricePerUnitLabel": "1L","availabilityChannels": ["IN_STORE", "ONLINE"],"category": "Fridge, Deli & Eggs > Milk > Fresh Milk"}
A free status row looks like this:
{"recordType": "status","status": "INVALID_INPUT","failureStage": "input","message": "Run setup rejected. Check input values, spending allowance and preview configuration. See SUMMARY for the error type or contact support with this run ID."}
🧠 Advanced usage
Track Pak'nSave price changes at one store daily
Keep storeId and the queries fixed, run once a day and diff price and pricePerUnit by id between datasets. A product missing from one day's results is an assortment change, not proof of a price change.
Scrape the Pak'nSave Pantry category
Set searchTerms: [] and categoryUrls: ["https://www.paknsave.co.nz/shop/category/pantry"] with a bounded maxItemsPerQuery and spending limit. Check SUMMARY.status is complete before treating the list as finished.
Continue a large Pak'nSave collection across runs
In paid mode set continuePreviousRun: true, previousStoreId to the prior run's default key-value store and previousQueueId to its CHECKPOINT_META.queueId, with the same store and queries. Buffered rows are delivered before new pages, results go to the new run's dataset, and each checkpoint can be claimed once. A recorded continuation on 2026-10-16 returned 54 rows with no overlap with the original run.
Compare Pak'nSave with Woolworths NZ and New World
This actor returns no barcodes, so match on normalised name plus packageSize against the Woolworths NZ Scraper or New World NZ Scraper and treat matches as candidates. Do not assume id values match across retailers.
🔌 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. A daily paid task with a fixed storeId and a spending limit suits price tracking; previews are a lifetime allowance, not something to schedule. Copy-paste code in Python, Node, curl and n8n: architek-earth/examples/paknsave-nz-scraper.
💸 Pricing
Pay per result. Platform and proxy usage are included. Status rows, failed requests and blocked pages are free. A continuation run skips products already delivered, but each productive continuation run pays the $0.15 collection fee again.
| Event | Price | What it covers |
|---|---|---|
| Free preview | $0 | 20 lifetime attempts per account; one page, up to 10 rows each. |
product | $4.00 / 1,000 products | One product row saved to the dataset in a paid run. |
collection-delivered | $0.15 per run | Charged once ($0.15) per paid run, after its first product is saved, including each productive continuation run. Zero-output runs are not charged. |
One paid run of 10 products costs $0.19; 100 products in one run cost $0.55; 1,000 products in one run cost $4.15. A paid run needs a spending limit of at least $0.154, or it is rejected before proxy setup.
❓ FAQ
Is there a Pak'nSave API for product prices? This actor is one: it returns Pak'nSave product and price data as JSON through the Apify API, callable from any language or from n8n, Make and Zapier.
Do I need a Pak'nSave account or login? No. No Pak'nSave account, cookies or loyalty card. An Apify account is required.
Can I get Pak'nSave prices for a specific store? Yes. Pass the store's public UUID as storeId; blank uses Royal Oak. Keep one store fixed for comparisons.
Does it return Pak'nSave specials, Club Deals or was-prices? Offers the source lists come back in promotions. There is no separate was-price or membership-price field.
Can I get Pak'nSave barcodes, nutrition or ingredients? No. This release returns no barcodes, nutrition, ingredients or images.
Does it show Pak'nSave stock levels? No. availability is always "unknown", and availabilityChannels only says whether a product is sold in store or online.
🤖 For AI agents & LLM apps
Paste this into your AI assistant:
architekture/paknsave-nz-scraper on Apify. Python: from apify_client import ApifyClient; client = ApifyClient("TOKEN"); run = client.actor("architekture/paknsave-nz-scraper").call(run_input={"searchTerms": ["milk"], "storeId": "e1925ea7-01bc-4358-ae7c-c6502da5ab12", "preview": False, "maxItemsPerQuery": 10, "proxyConfiguration": {"useApifyProxy": True, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "NZ"}}); items = client.dataset(run["defaultDatasetId"]).list_items().items (page with offset/limit for large exports). Rows with recordType == "status" are free and explain invalid input or a stopped run. Full input schema and README: GET https://api.apify.com/v2/acts/architekture~paknsave-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 — prices, club prices, specials
- New World NZ Scraper — store prices, Clubcard offers, promotions
- Pak'nSave Scraper — you are here
- 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 paknsave.co.nz, the same pages any visitor sees without logging in. It does not bypass authentication. It is not affiliated with or endorsed by Pak'nSave or Foodstuffs. 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-22 — Every run now writes
RUN_SUMMARY(same document asSUMMARY, which stays). A challenge page from the product API stops the run asBLOCKEDon the first response. A spending limit used up exactly by the last product now ends the run ascomplete. Pricing unchanged. - 2026-10-22 — Status message now reads
Done: N rows, M details, K status rows (STATUS). - 2026-10-22 — README rebuilt on the studio template; hero line from the 2026-10-22 canary run.
- 2026-10-21 — A malformed
storeIdnow returns a freeINVALID_INPUTstatus row before collection. - 2026-10-21 — Invalid input, blocks and time limits now stop cleanly with a free status row instead of a failed run; the collection deadline is clamped to the platform timeout.
- 2026-10-16 — Added actionable failed-run status messages for insufficient allowance, exhausted previews and rejected continuation. Failure summaries retain the stage, error type and partial row counts without exposing transport credentials.
- 2026-10-16 — Verified free preview, product/collection billing and continuation across a newly fetched page. Added zero-charge checks for insufficient allowance and consumed-checkpoint replay.
- 2026-10-16 — Verified anonymous product API, cent-to-NZD mapping, public store selection and Pantry filtering against saved real responses. Documented unsupported fields and source limits.
- 2026-10-16 — Prepared listing, priced examples and stable-field documentation from recorded runs; no production uptime or customer-demand claim.