Query Woolworths NZ product search, specials, category browse, and SKU details, plus a user's own past orders, favourites, saved lists, and trolley when they explicitly provide account credentials. Manage the user's saved lists or trolley only when they explicitly request a specific change.
Scanned 9/10/2026
Install to Claude Code
npx -y skills add thecolab-ai/.skills --skill woolworths-nz --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Woolworths Nz?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/thecolab-ai-woolworths-nz)More formats (shields.io, HTML) on the badges page.
---
name: woolworths-nz
description: "Query Woolworths NZ product search, specials, category browse, and SKU details, plus a user's own past orders, favourites, saved lists, and trolley when they explicitly provide account credentials. Manage the user's saved lists or trolley only when they explicitly request a specific change."
license: MIT
compatibility: "Requires Python 3.10+ and network access; first account login additionally requires the optional Camoufox browser package"
metadata:
thecolab.category: "food-and-fuel"
thecolab.source_owner: "Woolworths New Zealand"
thecolab.source_type: "commercial"
thecolab.auth: "mixed"
thecolab.access_mode: "authenticated-personal"
thecolab.data_class: "personal"
thecolab.writes: "true"
thecolab.browser: "true"
thecolab.risk: "high"
thecolab.cache_ttl: "30m"
thecolab.schema_version: "1"
thecolab.skill_type: "authenticated-personal"
thecolab.pack: "nz-personal-data"
thecolab.public_pack: "nz-commercial-web"
thecolab.public_commands: "search,specials,categories,browse,product"
thecolab.public_description: "Query Woolworths NZ public product search, specials, categories, browsing, and SKU details without an account."
thecolab.public_access_mode: "public-api"
thecolab.public_health: "healthy"
thecolab.public_risk: "medium"
thecolab.public_allowed_domains: "www.woolworths.co.nz"
thecolab.source_url: "https://www.woolworths.co.nz"
thecolab.allowed_domains: "auth.woolworths.co.nz,iam.woolworths.co.nz,www.woolworths.co.nz"
thecolab.last_verified: "2026-09-02"
thecolab.health: "gated"
thecolab.maintainer: "@adam91holt"
thecolab.mutations: "authenticated-api-post,authenticated-api-delete"
---
# Woolworths NZ
## Goal
Query live Woolworths NZ product data, optionally retrieve the authenticated user's own account history, and perform explicit saved-list or trolley changes through one CLI.
## Use this when
- A user asks for Woolworths NZ product prices, specials, keyword search, or SKU details
- A user explicitly wants their own past Woolworths orders, favourites, or saved lists
- A user wants their own Woolworths tax-invoice PDF enriched with the matching past-order SKUs
- A user explicitly asks to create/delete a saved list or add, update, or remove a list product
- A user explicitly asks to inspect their trolley or add, update, remove, or clear its products
## Do not use this for
- Woolworths Australia or another retailer
- Checkout, ordering, payment, delivery-slot, fulfilment, account, or Everyday Rewards changes
- List or trolley mutation the user has not explicitly requested
- Reading another person's account or using credentials not supplied by the account holder
- Redistributing Woolworths product or account data as a dataset
- Historical pricing claims unless another source provides history
## Preferred workflow
1. Run `scripts/cli.py` with the narrowest command that answers the task
2. Use public `search`, `specials`, `categories`, `browse`, and `product` commands without credentials
3. Use account commands only after the user supplies their own credentials as environment variables
4. Run saved-list or trolley mutations only for the exact change the user requested
5. Preserve every `--yes` deletion/removal guard
6. Use `--json` only for private structured workflows; treat account JSON as personal data
7. For invoice enrichment, use the local tax-invoice PDF and its matching order ID; inspect unmatched or ambiguous joins before relying on them
8. Never use this skill to place an order or perform checkout/payment actions
## Authentication and privacy
Public product commands need no account. Personal commands require:
```bash
export WOOLWORTHS_USERNAME='member@example.nz'
export WOOLWORTHS_PASSWORD='...'
woolworths auth login
```
- `WOOLWORTHS_EMAIL` is accepted as an alias for `WOOLWORTHS_USERNAME`.
- The CLI registers and displays account commands only when both a username/email and `WOOLWORTHS_PASSWORD` exist in its environment.
- The password is passed only to Woolworths' browser login and is never written to disk.
- The cookie cache stores a SHA-256 hash of the normalised username and is reused only when it matches the currently supplied username. Changing accounts invalidates the old cache instead of silently reusing it.
- Woolworths' login page uses a browser challenge. Install the optional helper with `python3 -m pip install camoufox`, then run `python3 -m camoufox fetch` once.
- A reusable cookie cache is written to `~/.local/state/woolworths-nz/cookies.json` with file mode `0600`.
- Authenticated responses can refresh Woolworths session/Akamai cookies; the CLI persists only cookies scoped to `woolworths.co.nz` back into the same private, account-bound cache.
- Override the cache location with `WOOLWORTHS_SESSION_FILE`.
- If a hidden browser login cannot complete a challenge, retry `auth login --headed`.
- `auth status` never emits cookies or account details. `auth logout` removes only the local cookie cache; it does not sign out other devices or mutate the account.
- Orders, list names, favourites, item history, addresses, and raw account JSON are personal data. Do not paste them into shared logs, issues, or pull requests.
- Tax invoices and enriched invoice output are personal financial/order data. Never add a user's PDF or parsed rows to fixtures or source control.
## CLI
Run with:
```bash
python3 skills/woolworths-nz/scripts/cli.py <command> [flags]
```
Public commands are always available:
- `search <query> [--limit N] [--page N] [--size text] [--json]`
- `specials [query] [--limit N] [--page N] [--json]`
- `categories [parent-category-key] [--json]`
- `browse <category-key> [--limit N] [--page N] [--json]`
- `product <sku...> [--json]`
The following appear only when the credential environment variables are set:
- `auth login [--headed]`
- `auth status [--json]`
- `auth logout`
- `orders [--page N] [--date-filter value] [--json]`
- `order <order-id> [--json]`
- `order-items <order-id|all> [--page N] [--limit N] [--sort value] [--json]`
- `invoice-items <order-id> <invoice.pdf> [--min-confidence 0..1] [--json]`
- `favourites [--page N] [--limit N] [--sort value] [--json]`
- `lists [--json]`
- `list <list-id> [--page N] [--limit N] [--sort value] [--json]`
- `list-create <name> [--source empty|trolley|favourites|list|order|all-orders] [--source-id id] [--json]`
- `list-delete <list-id> --yes [--json]`
- `list-add <list-id> <sku> [--quantity N] [--json]`
- `list-update <list-id> <sku> --quantity N [--json]`
- `list-remove <list-id> <sku> --yes [--json]`
- `cart [--json]`
- `cart-add <sku> [--quantity N] [--unit Each|Kg] [--json]`
- `cart-update <sku> --quantity N [--unit Each|Kg] [--json]`
- `cart-remove <sku> --yes [--unit Each|Kg] [--json]`
- `cart-clear --yes [--json]`
Examples:
```bash
python3 skills/woolworths-nz/scripts/cli.py search milk --limit 10
python3 skills/woolworths-nz/scripts/cli.py categories
python3 skills/woolworths-nz/scripts/cli.py product 705692 --json
woolworths auth login
woolworths orders --json
woolworths invoice-items <order-id> ~/Downloads/invoice.pdf --json
woolworths lists
woolworths list-create "Weekly shop"
woolworths list-add <list-id> 705692 --quantity 2
woolworths cart-add 705692 --quantity 2
```
Trolley SKU commands resolve `--unit Each|Kg` to the exact purchasing variant
before mutating. Pass the exact variant key when a product has other ambiguous
purchasing variants.
`list-create` defaults to `--source empty`. Woolworths currently implements
that safely by saving the current trolley as a list, so the CLI first reads the
trolley and refuses to create the list unless it is empty. Use
`--source trolley` explicitly only when the user wants the trolley contents
copied into the new list.
## Resources
- CLI entrypoint: `scripts/cli.py`
- Current GraphQL documents and parsers: `scripts/graphql_api.py`
- Browser login helper: `scripts/browser_auth.py`
- Invoice parser and SKU matcher: `scripts/invoice_parser.py`
- Live and deterministic smoke tests: `scripts/smoke_test.py`
- API and stability notes: `references/api-notes.md`
## Notes
- Public commands use Woolworths' current GraphQL product service, remain stdlib-only, and do not launch a browser.
- Account reads/writes use the saved Woolworths session directly; a 401/403 triggers one browser refresh and retry.
- `invoice-items` parses supplied/paid invoice rows from a text-based Woolworths tax-invoice PDF, verifies its Order Confirmation/Invoice Number against the requested order ID, fetches the matching past-order product list, and performs a one-to-one confidence-scored name join to SKUs.
- Invoice parsing has one additional optional dependency: `python3 -m pip install pdfplumber`. It is imported only by `invoice-items`; public product commands remain standard-library-only.
- A match below `--min-confidence` is left unmatched. Close runner-up candidates are marked ambiguous rather than silently accepted.
- Safe reads may refresh an expired session once. Mutations are never replayed after an indeterminate non-JSON response; inspect the current list or trolley state before retrying.
- Saved-list item writes use Woolworths' current `{itemsToAdd: [{sku, quantity}]}` request.
- Trolley reads and writes use the current `CustomerCart`, `SetCartLineItemQuantity`, and `ClearCart` GraphQL operations. Woolworths writes target a product variant key; callers may still pass a catalogue SKU and the CLI resolves its current variant key first. `cart-add` reads then increments; `cart-update` sets the target.
- `Each` quantities must be whole numbers. Use `--unit Kg` for explicit weights.
- List deletion, list item removal, trolley item removal, and trolley clearing require `--yes`.
- Endpoint shapes can change; retry with a fresh session before assuming account data is unavailable.
- This is an unofficial integration and deliberately excludes checkout/order placement.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!