# Woolworths Australia price scraper — specials, unit price (`dropin-apis/woolworths-au-products`) Actor

Woolworths Australia price scraper for shelf price, was-price, specials, and unit price (per kg or litre) by search term. Public catalog, no login. Category browsing is not included. $1 per 1,000 products.

- **URL**: https://apify.com/dropin-apis/woolworths-au-products.md
- **Developed by:** [drop-in apis](https://apify.com/dropin-apis) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 item scrapeds

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

## Woolworths Australia price scraper — specials, unit price

**Woolworths Australia prices** by search term: shelf price, was-price, specials and unit price (per kg or litre), from the public product-search catalog. No login. $1 per 1,000 products.

Last updated: 2026-10-02 · **Guide:** https://alidaram99.github.io/api-alternatives/woolworths-api/

Uses Apify's Australian residential proxy by default, because Woolworths blocks datacenter IPs. Only public catalog data is collected.

### Use cases

- **Price monitoring:** track your own or a competitor's shelf prices over time.
- **Grocery inflation research:** collect price/unit-price data across staple search terms on
  a schedule.
- **Competitor pricing:** compare specials, savings and unit pricing across product ranges.

### Input

| Field | Type | Description |
|---|---|---|
| `searchTerms` | array (required) | Search terms, e.g. `["milk", "bread"]`. Each term is paginated independently. |
| `categoryUrls` | array | Reserved for future category-browsing support — **not yet implemented**, see Limits. |
| `maxItemsPerSearch` | integer | Stop after this many items per search term. Default 100. |
| `sortBy` | string | `relevance` | `priceAsc` | `priceDesc` | `unitPriceAsc` | `name`. Applied client-side — see FAQ. |
| `includeUnavailable` | boolean | Include out-of-stock/unavailable items. Default `false`. |
| `proxyConfiguration` | object | Standard Apify Proxy editor. **Defaults to Apify Residential proxy in Australia** — see FAQ "Why Residential proxy?" for why. |

Example input:

```json
{
  "searchTerms": ["milk", "bread", "eggs"],
  "maxItemsPerSearch": 100,
  "sortBy": "priceAsc",
  "includeUnavailable": false
}
```

(`proxyConfiguration` is omitted here deliberately — leaving it out uses the Residential-AU
default, which is what you want in almost every case.)

### Output

One row per product:

```json
{
  "stockcode": "888140",
  "name": "Woolworths Full Cream Milk",
  "brand": "Woolworths",
  "description": "Woolworths Full Cream Milk 3L",
  "packageSize": "3L",
  "price": 4.95,
  "wasPrice": 4.95,
  "isOnSpecial": false,
  "savingsAmount": 0,
  "cupPrice": 1.65,
  "cupMeasure": "1L",
  "cupString": "$1.65 / 1L",
  "isAvailable": true,
  "isInStock": true,
  "unit": "Each",
  "imageUrl": "https://cdn1.woolworths.media/content/wowproductimages/medium/888140.jpg",
  "productUrl": "https://www.woolworths.com.au/shop/productdetails/888140/woolworths-full-cream-milk",
  "categories": [],
  "rating": 0,
  "reviewCount": 0,
  "searchTerm": "milk",
  "scrapedAt": "2026-10-02T00:14:46.726Z"
}
```

No customer data of any kind is collected — only public catalog/pricing fields.

### How it compares

| Option | What you get | Price | Notes |
|---|---|---|---|
| **This Actor** | Price, was-price, specials, unit price, stock flags, image and product URL | $1 per 1,000 products | Residential AU proxy by default; search terms only (no category URLs yet) |
| Other Woolworths Actors on Apify | Similar product data | Varies widely between Actors | Compare success rate, unit-price fields and proxy handling |
| Woolworths website | Same public data, by hand | Free | No export |

### Pricing

**$0.001 per item** ($1 per 1,000 products), pay-per-event. Proxy and compute costs are covered by the Actor's price, not added to your bill.

### FAQ

#### Is there a Woolworths API for prices?

Woolworths has no public product API for this. This Actor collects the public product-search catalog by search term and returns clean JSON or CSV.

#### What price fields do I get?

Current price, was-price, special flag, savings amount and unit price (`cupPrice`, `cupMeasure`, `cupString`, e.g. "$1.70 / 1L"), plus name, brand, package size, stock flags, image and product URL.

#### Can I scrape a Woolworths category URL?

Not in this version. `categoryUrls` is accepted and has no effect. Use `searchTerms`.

#### Why does it use an Australian residential proxy?

This Actor's own original local testing (from an ordinary home
internet connection) worked fine calling Woolworths directly, with no proxy at all. **On Apify's
own infrastructure, Woolworths returns HTTP 403 to Apify's datacenter IP ranges — and to direct,
no-proxy requests from Apify — but works through Apify's Residential proxy in Australia**,
confirmed with a real live run. That's why the default changed to Residential AU rather than
"no proxy": it's the one option actually confirmed to work on the platform this Actor runs on,
not just on the machine it was built on. If you turn the default off, the Actor still switches
to it automatically the first time it sees an HTTP 403 with no proxy in effect, and fails
loudly (rather than returning nothing) if that automatic fallback isn't available to your
account. See `VERIFY.md` §R1 for the live evidence, the proxy-cost measurement, and the
citations on who pays for proxy bandwidth under this Actor's pricing model.

#### Do I pay extra for the proxy?

No. Under this Actor's pay-per-event pricing, platform costs (proxy bandwidth included) are paid out of the Actor's own revenue share. You pay only the per-product price.

#### How many products per page?

Up to 36, Woolworths' own limit. The Actor pages through results up to `maxItemsPerSearch`.

#### Why does `sortBy` say it is applied client-side?

Woolworths' own sort parameter had no effect over this interface (every value returned identical ordering), so the Actor sorts the results it collected.

#### What does it cost?

$0.001 per product ($1 per 1,000). No subscription.

### Limits

- **Category browsing is not implemented.** `/apis/ui/Browse/Category` exists and is allowed
  by robots.txt, but a plain `GET` returns `"CategoryId is required"` — the endpoint expects a
  `CategoryId`/`Url`/`FormatObject` request shape that wasn't pinned down in this version. Use
  `searchTerms` instead.
- Up to 36 items per page (Woolworths' own hard limit; confirmed live — `pageSize=48` returns
  `"Page size should not be greater than the limit: 36"`).
- Only public catalog/pricing data — no customer accounts, no checkout, no personal data.
- Requires Apify Residential proxy (the default) to work reliably on Apify's own infrastructure
  — see FAQ "Why Residential proxy?". Residential proxy bandwidth is a real, measured cost on
  top of this Actor's $1/1,000 price — see `VERIFY.md` §R1 for the measured amount and for
  who actually bears that cost under this pricing model.

### Verified on Apify

Verified live on Apify's own infrastructure on 2026-10-02: datacenter IPs get HTTP 403 from Woolworths, and the default residential AU proxy works. A 98-item run succeeded with 0 rejected items, and the nightly health check passes. Measured platform cost is about $0.025 per 1,000 items, proxy included, and is paid by the Actor's revenue share. Details are in `VERIFY.md` §R1.

# Actor input Schema

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

Search terms to look up, e.g. "milk", "bread". Each term is paginated independently up to maxItemsPerSearch.

## `categoryUrls` (type: `array`):

Reserved for future category-browsing support. A permitted /apis/ui/Browse/Category endpoint exists but its request contract (CategoryId/Url/FormatObject) was not reverse-engineered in this version — providing values here is accepted but has no effect yet. Use searchTerms instead.

## `maxItemsPerSearch` (type: `integer`):

Stop paginating a search term once this many items have been collected (pages of up to 36 items each — Woolworths' own limit).

## `sortBy` (type: `string`):

Applied client-side after collection (the live endpoint's own sort parameter was found to have no effect over this interface — see README).

## `includeUnavailable` (type: `boolean`):

By default, items that are not available or not in stock are dropped.

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

Defaults to Apify Residential proxy in Australia. Confirmed live on Apify's own infrastructure: Woolworths returns HTTP 403 to Apify's datacenter IP ranges (and to direct, no-proxy requests) there, even though this Actor's own local verification worked without a proxy from a residential home connection — see README "Why Residential proxy". If you turn this off, the Actor still automatically switches to Residential AU the first time it sees an HTTP 403 with no proxy in effect, and fails with a clear error only if that isn't available to your account.

## Actor input object example

```json
{
  "searchTerms": [
    "milk"
  ],
  "maxItemsPerSearch": 5,
  "sortBy": "relevance",
  "includeUnavailable": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "AU"
  }
}
```

# Actor output Schema

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

All items in the run's default dataset.

# 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"
    ],
    "maxItemsPerSearch": 5,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "AU"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dropin-apis/woolworths-au-products").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"],
    "maxItemsPerSearch": 5,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "AU",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("dropin-apis/woolworths-au-products").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"
  ],
  "maxItemsPerSearch": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "AU"
  }
}' |
apify call dropin-apis/woolworths-au-products --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dropin-apis/woolworths-au-products"
        }
    }
}
```

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/3kDd5OZlTBEZ3w0Wz/builds/H36RstGPgTXR7HFb3/openapi.json
