# Coles Scraper: Prices, Specials, Stock by Store (`themineworks/coles-scraper`) Actor

Scrape Coles Australia products and prices by keyword, category, specials or product link: price, was price, half price and multi buy offers, unit price per kg or litre, stock, barcode, nutrition, category. Prices and stock by store or postcode. Monitor mode returns price changes only.

- **URL**: https://apify.com/themineworks/coles-scraper.md
- **Developed by:** [The Mine Works](https://apify.com/themineworks) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.63 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Coles Scraper: Prices, Specials, Stock by Store

[![6,725 Coles products with price, unit price, specials and stock in 165 seconds](https://api.apify.com/v2/key-value-stores/cUXz95yxflDho41nn/records/coles-scraper-hero.png)](https://console.apify.com/actors/37fxb2VZqudCE2NKP/input?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

From **The Mine Works**, makers of [ALDI Australia Scraper](https://apify.com/themineworks/aldi-australia-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral) and [B2B Leads Finder](https://apify.com/themineworks/b2b-leads-finder?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral), with over 290,000 runs across 310+ public actors.

Updated 31 Oct 2026: first release. Keywords, categories by name, slug or link, the full catalogue, all specials, half price, multi buy and online only specials, product links and ids; prices and stock for chosen stores or postcodes; barcode, ingredients and nutrition; monitor mode that returns only price changes; one flat row per product. Bookmark this Actor on its Store page so it is one click away next time.

### Why choose this actor?

- **Every price a category manager compares, in columns.** `price`, `was_price`, `save_amount`, `is_half_price` and the multi buy offer split into `multibuy_quantity` and `multibuy_total_price`. Coles shows some unit prices per 100 g and others per kg; `unit_price_normalized` puts every row on one scale (per kg, per litre or each), so a whole aisle sorts by real value.
- **Each store's own price and stock.** Give store ids or postcodes and every list is read once per store, each row carrying `store_id`, `store_name` and `store_state`. In our test the same Tim Tam Original 200g was $4.50, was $6.42 with 279 packs at Coles Karratha, and $4.50, was $6.00 with 557 packs at Coles Collingwood.
- **Cheap to run every day.** Monitor mode remembers the last price of each product and returns only what changed, so a daily watch of 2,000 products pays for the dozens that moved, not the 2,000. Plain HTTP to the data coles.com.au loads itself, no browser.
- **Pay per product, nothing for errors.** Links that are not Coles links, unknown store ids, the summary row and duplicates found by two lists are never charged. No Coles account.

[![Run it on Apify](https://api.apify.com/v2/key-value-stores/cUXz95yxflDho41nn/records/button-run.png)](https://console.apify.com/actors/37fxb2VZqudCE2NKP/input?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

**Part of The Mine Works E-commerce and marketplaces family:** [Ozon.ru Scraper](https://apify.com/themineworks/ozon-product-search?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral), [⭐ Amazon Reviews Scraper](https://apify.com/themineworks/amazon-reviews?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral), [Amazon Product Scraper](https://apify.com/themineworks/amazon-products?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral), [Etsy Listings Scraper](https://apify.com/themineworks/etsy-search-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral), [AliExpress Scraper](https://apify.com/themineworks/aliexpress-products?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral), [Kleinanzeigen.de Scraper](https://apify.com/themineworks/kleinanzeigen-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral).

### Try it in one minute

Paste this into the input (JSON view) and press Start. It returns the first 30 products for "milk" at Coles' default online store. It took 7 seconds in our test run:

```json
{
  "searchQueries": ["milk"],
  "maxItems": 30
}
```

Put several keywords on separate lines, add categories or a specials list, or paste product links. A product that two of your lists find is delivered once per store.

Apify's free plan includes $5 of credit every month, which covers about 5,300 products at this actor's price.

#### Copy to your AI assistant

```text
themineworks/coles-scraper on Apify. Reads Coles Australia (coles.com.au) by keyword, category, specials list or product link and returns one flat row per product with price, was price, special and multi buy offer, unit price and a unit price per kg or litre, stock quantity, purchase limit, department, category and aisle, image and link, for Coles' default online store or chosen stores, with no login. Call ApifyClient("TOKEN").actor("themineworks/coles-scraper").call(run_input={"searchQueries": ["milk"], "maxItems": 100}), then client.dataset(run["defaultDatasetId"]).list_items().items. Inputs: searchQueries (keywords or any coles.com.au link), categories (names such as Milk, slug paths such as dairy-eggs-fridge/milk, browse links, or "all"), specials (none, all, halfprice, multibuy, onlineonly), productUrls (product links or ids), storeIds (store ids such as 313 or store page links), postcodes (4 digit postcodes, nearest Coles that sells online), fullCatalogue (bool), maxItems (default 100, per list and store), sortBy (recommendedDescending, priceAscending, priceDescending, unitPriceAscending, productNameAscending, productNameDescending, salesDescending), includeDetails (bool, adds barcode, ingredients, allergens, nutrition, country of origin, images to list rows), includeSponsored (default true), monitorMode (bool) with monitorName, monitorWatch (price or all) and includeNewProducts, residentialRetry (default true). Product rows have no _type field and carry retailer, product_id, barcode, name, brand, display_name, description, size, price, was_price, currency, on_special, promotion_type, special_type, price_description, is_half_price, offer_description, save_amount, save_percent, save_statement, multibuy_quantity, multibuy_unit_price, multibuy_total_price, online_special, unit_price, unit_price_quantity, unit_price_unit, unit_price_display, unit_price_normalized, unit_price_normalized_unit, sold_by_weight, in_stock, availability_type, stock_quantity, purchase_limit, promotional_purchase_limit, age_restricted, department, category, subcategory, category_path, department_id, category_id, subcategory_id, merchandise_hierarchy, fresh_life, variations_count, image_url, images, url, is_sponsored, long_description, ingredients, allergens, dietary, lifestyle, storage, dimensions, nutrition, serving_size, servings_per_pack, country_of_origin, details_scraped, store_id, store_name, store_state, store_postcode, price_scope, specials_filter, found_by, search_keyword, search_category, sort_by, results_in_list, page, position, scraped_at, and in monitor mode change_type, changed_fields, previous_price, previous_was_price, price_change, price_change_percent, previous_scraped_at. Each run also writes one row with _type "summary", one with _type "info" when products were delivered, and a row with _type "error" for each input that could not be read; none of these is charged. Full spec: GET https://api.apify.com/v2/acts/themineworks~coles-scraper/builds/default (Bearer TOKEN), which returns inputSchema and readme. Token: https://console.apify.com/account/integrations?fpr=ymnoit&utm_source=apify-readme&utm_medium=referral
```

### Key features

- **Keywords, categories, specials or links.** Type keywords as in the coles.com.au search box, give categories by name (Milk, Soft Drinks), slug path (dairy-eggs-fridge/milk) or link, pick a specials list, or paste any Coles link into any field: product, category, specials, search or store page.
- **Store prices.** Coles prices, was prices and stock differ by store. `storeIds` takes the number at the end of a store page link; `postcodes` takes the nearest Coles supermarket that sells online, and skips a store without an online range for the next nearest. Up to 50 stores per run.
- **The whole catalogue.** `fullCatalogue` (or `categories: ["all"]`) reads all 18 departments. Coles serves the first 5,000 products of any one list, so a bigger list is read category by category: Pantry (6,113 products) came back as 6,106 in our test.
- **Barcode and nutrition.** Product links always come with the barcode (GTIN), ingredients, allergens, dietary and storage text, nutrition panel per serve and per 100 g, country of origin and all images. `includeDetails` adds the same to list rows, one extra call per 24 products (96 products with details took 41 seconds in our test, barcode on 95).
- **Monitor mode.** Remembers the last price of each product per store and returns only new products and those whose price or was price moved (`monitorWatch: "all"` adds specials starting or ending and stock changes), with `previous_price`, `price_change` and `price_change_percent`.
- **Stops cleanly.** A run ends after the first call if Coles refuses it, after 6 refused calls in a row, at the last page of a list or at `maxItems`, and before its time limit, keeping every row. The summary row says why.

### How to use it

#### Basic: products for a keyword

```json
{
  "searchQueries": ["coffee beans", "oat milk"],
  "maxItems": 200
}
```

Each keyword is its own list, labelled in `search_keyword`, in Coles' relevance order.

#### A whole category, cheapest per litre first

```json
{
  "categories": ["Milk"],
  "sortBy": "unitPriceAscending",
  "maxItems": 500
}
```

`category_path` names the aisle of each product (Dairy, Eggs & Fridge > Milk > Full Cream Milk). Categories without a sort come back A to Z, which keeps long lists complete and stable between runs.

#### This week's half price specials in three states

```json
{
  "specials": "halfprice",
  "postcodes": ["2000", "3000", "6000"],
  "maxItems": 5000
}
```

Coles changes its specials on Wednesday; schedule this for Wednesday morning. Every row carries `store_id`, `store_name` and `store_state`.

#### Daily price change alerts

```json
{
  "categories": ["dairy-eggs-fridge", "pantry/coffee"],
  "monitorMode": true,
  "monitorName": "dairy-and-coffee",
  "includeNewProducts": false
}
```

The first run saves the baseline and returns nothing, so it costs nothing: the start fee is charged only once a product row is stored. Every run after it returns the products whose price or was price changed, with `change_type` `price_down` or `price_up`. Unchanged products are not delivered and not charged.

#### One product at a time from Clay, n8n or an AI agent

```json
{
  "productUrls": ["https://www.coles.com.au/product/coles-full-cream-milk-3l-8150288"],
  "storeIds": ["313"]
}
```

One row with the price, was price and barcode of that product at Coles Karratha. A bare product id (8150288) works too. Product links come back 24 to a call; the stock quantity comes on list rows only (`in_stock` is on both).

### Input parameters

| Parameter | Type | Default | What it does |
|---|---|---|---|
| `searchQueries` | array of strings | empty | Keywords, or any Coles link. |
| `categories` | array of strings | empty | Category names, slug paths or links; `all` for every department. |
| `specials` | string | `none` | `all`, `halfprice`, `multibuy` or `onlineonly`. |
| `productUrls` | array of strings | empty | Product links or product ids, 24 per call, with barcode and full details. |
| `storeIds` | array of strings | empty | Coles store ids or store page links. |
| `postcodes` | array of strings | empty | Postcodes; the nearest Coles that sells online. |
| `fullCatalogue` | boolean | `false` | Every department. |
| `maxItems` | integer | `100` | Most products per list and store, 1 to 30,000. |
| `sortBy` | string | relevance for keywords, name A to Z for lists | Any Coles sort order. |
| `includeDetails` | boolean | `false` | Barcode, ingredients, nutrition and images on list rows. |
| `includeSponsored` | boolean | `true` | Keep Coles' paid placements (marked `is_sponsored`). |
| `monitorMode` | boolean | `false` | Return only products that changed since the last run. |
| `monitorName` | string | `default` | Separate price memories for separate watch lists. |
| `monitorWatch` | string | `price` | `all` also counts specials and stock changes. |
| `includeNewProducts` | boolean | `true` | Return products the monitor has not seen before. |
| `residentialRetry` | boolean | `true` | Use Australian residential IPs for pages Coles refuses on datacenter IPs. |

Give `searchQueries`, `categories`, `specials`, `productUrls` or any mix. Up to 100 lists and 5,000 product links per run.

### What data do you get?

One row per product and store. Product rows have no `_type` field; the summary, info and error rows do, so a filter on `_type` separates them.

| Field | What it is |
|---|---|
| `product_id`, `barcode` | Coles product id; barcode (GTIN) with product links or `includeDetails` |
| `name`, `brand`, `display_name`, `description`, `size` | Product, brand, brand with name and size, Coles' short text, pack size |
| `price`, `was_price`, `currency` | Price now, price before the special, AUD |
| `on_special`, `promotion_type`, `special_type`, `price_description` | Special flag, Coles promotion type (SPECIAL, EVERYDAY, NEW), special type (PERCENT_OFF, MULTI_SAVE), label such as 1/2 Price |
| `is_half_price`, `save_amount`, `save_percent`, `save_statement` | Half price flag and the saving |
| `offer_description`, `multibuy_quantity`, `multibuy_unit_price`, `multibuy_total_price` | Multi buy offer, e.g. Pick any 2 for $5 |
| `online_special` | Special online only |
| `unit_price`, `unit_price_quantity`, `unit_price_unit`, `unit_price_display` | Unit price as Coles shows it, e.g. $2.25/ 100g |
| `unit_price_normalized`, `unit_price_normalized_unit` | The same per kg, per litre or each |
| `sold_by_weight` | Price is for an approximate weight |
| `in_stock`, `availability_type`, `stock_quantity` | Availability at the store and the units Coles reports (stock quantity on list rows) |
| `purchase_limit`, `promotional_purchase_limit` | Most units per order, normally and on special |
| `age_restricted` | Liquor or tobacco |
| `department`, `category`, `subcategory`, `category_path` and their ids | Where the product sits on coles.com.au |
| `merchandise_hierarchy` | Coles' internal grouping (trade profit centre, category group, class) |
| `fresh_life`, `variations_count` | Shelf life guarantee, other sizes and varieties |
| `image_url`, `images`, `url` | Main image, all images (details), product page |
| `is_sponsored` | Paid placement |
| `ingredients`, `allergens`, `dietary`, `lifestyle`, `storage`, `dimensions`, `long_description` | Product page text (details) |
| `nutrition`, `serving_size`, `servings_per_pack`, `country_of_origin` | Nutrition panel per serve and per 100 g, origin (details) |
| `store_id`, `store_name`, `store_state`, `store_postcode`, `price_scope` | The store the prices are for |
| `found_by`, `search_keyword`, `search_category`, `specials_filter`, `sort_by`, `results_in_list`, `page`, `position` | The list that found the product and its place in it |
| `change_type`, `changed_fields`, `previous_price`, `previous_was_price`, `price_change`, `price_change_percent`, `previous_scraped_at` | Monitor mode only |
| `scraped_at` | When the row was written |

**Summary row** (`_type: "summary"`, never charged): lists read and failed, products delivered and charged, duplicates skipped, stores with the store each postcode resolved to, requests, refused calls, kilobytes on the wire, `per_list` (one entry per list with products found, delivered and why it stopped) and `shortfall_reason` when fewer products came back than asked. The same summary is saved as the `OUTPUT` record of the run.

**Error rows** (`_type: "error"`, never charged): one per input that could not be read, with `error_type` (`invalid_input`, `not_found`, `category_not_found`, `store_not_online`, `postcode_not_found`, `blocked`, `fetch_error`), `identifier` and `reason`.

#### Stable fields for automations

These were present in every product row of our test runs (6,725 rows from Dairy, Eggs & Fridge and Pantry), and their names will not change:

| Field | What it is |
|---|---|
| `product_id` | The key to store and join on (with `store_id`) |
| `display_name` | Brand, name and size |
| `brand` | Brand |
| `on_special` | Special flag |
| `is_half_price` | Half price flag |
| `in_stock` | Availability |
| `image_url` | Main image |
| `url` | Product page |
| `store_id` | Store the prices are for |
| `position` | Place in its list |

Nearly always present: `price` (6,694 of 6,725; products Coles shows as unavailable have no price), `size`, `category_path`, `stock_quantity` (6,699), `purchase_limit`, `unit_price_display` and `unit_price_normalized` (6,465: some products, such as gift cards, have no unit price). Present when the product is on special: `was_price`, `save_amount` (1,453 of 6,725), multi buy fields (575). Barcode and nutrition fields need product links or `includeDetails`.

#### Output examples

A product at a chosen store, from the keyword "tim tam original" with `storeIds: ["313"]` (test run, 30 Oct 2026, trimmed):

```json
{
  "retailer": "Coles",
  "product_id": "329607",
  "display_name": "Arnott's Tim Tam Chocolate Biscuits Original 200g",
  "brand": "Arnott's",
  "size": "200g",
  "price": 4.5,
  "was_price": 6.42,
  "on_special": true,
  "save_amount": 1.92,
  "unit_price_display": "$2.25/ 100g",
  "unit_price_normalized": 22.5,
  "unit_price_normalized_unit": "kg",
  "in_stock": true,
  "stock_quantity": 279,
  "purchase_limit": 20,
  "category_path": "Chips, Chocolates & Snacks > Biscuits & Cookies > Chocolate Biscuits",
  "image_url": "https://cdn.productimages.coles.com.au/productimages/3/329607.jpg",
  "url": "https://www.coles.com.au/product/arnott's-tim-tam-chocolate-biscuits-original-200g-329607",
  "store_id": "313",
  "store_name": "Coles Karratha",
  "store_state": "WA",
  "price_scope": "store",
  "found_by": "keyword_search",
  "position": 1
}
```

A multi buy special from the Dairy, Eggs & Fridge department (same day, trimmed):

```json
{
  "product_id": "2807164",
  "display_name": "Pauls Zymil Full Cream Long Life Milk 1L",
  "price": 3,
  "on_special": true,
  "special_type": "MULTI_SAVE",
  "offer_description": "Pick any 2 for $5",
  "multibuy_quantity": 2,
  "multibuy_unit_price": 2.5,
  "multibuy_total_price": 5,
  "unit_price_display": "$3.00/ 1L",
  "stock_quantity": 146,
  "category_path": "Drinks > Long-Life Milk > Lactose Free Milk",
  "store_id": "7674",
  "price_scope": "default_online_store"
}
```

A product link (details always on, trimmed):

```json
{
  "product_id": "8150288",
  "display_name": "Coles Full Cream Milk 3L",
  "price": 4.95,
  "barcode": "9300601186945",
  "ingredients": "Homogenised and Pasteurised Full Cream Milk.",
  "allergens": "Contains Milk",
  "country_of_origin": "Australian Milk",
  "serving_size": "250mL",
  "nutrition": { "per_100g": { "Energy (kJ)": "258 kJ", "Protein": "3.4 g", "Calcium": "118 mg" } },
  "found_by": "product"
}
```

An error row for a store id without an online range (nothing charged):

```json
{ "_type": "error", "error_type": "store_not_online", "identifier": "99999", "reason": "Coles shows no online prices for store 99999: it does not exist or has no online range. Use a store that sells online, or a postcode for the nearest one." }
```

### Pricing

Pay per event: you pay for the products you receive, plus a flat $0.003 per run, whatever memory you choose. Barcode and nutrition reads and store prices cost nothing extra.

| Event | When it is charged | Free plan | Bronze (Starter) | Silver (Scale) | Gold (Business) |
|---|---|---|---|---|---|
| `product-scraped` | Once per product row stored in your dataset | $0.90 per 1,000 | $0.81 per 1,000 | $0.72 per 1,000 | $0.63 per 1,000 |
| `run-start` | Once per run, after the first product row is stored | $0.003 | $0.003 | $0.003 | $0.003 |

The price of one product is the price per 1,000 divided by 1,000.

Never charged:

- links that are not Coles links, unknown product ids and store ids (each gets an error row);
- a product that a second list of the same run finds again for the same store;
- products past your `maxItems`, and sponsored products when `includeSponsored` is off;
- unchanged products in monitor mode, and new ones when `includeNewProducts` is off;
- the summary, info and error rows;
- a run that delivers no product: the start fee is charged only after the first product row is stored;
- anything past your "Max cost per run". The actor checks the budget before each batch of rows and stops while the total is still below your limit, so the run ends SUCCEEDED with a partial result and a status message saying so.

### Run it on a schedule

1. Open the actor in Apify Console, set your input and click **Save as a new task**.
2. In the task, open **Schedules**, click **Add schedule** and pick how often (every day, every Wednesday at 07:00 for the new specials, and so on).
3. Turn on `monitorMode` in the task so each run returns only the products whose price changed, or compare runs yourself on `product_id`, `store_id` and `price`.
4. Optional: add an integration (Google Sheets, Slack, a webhook) so each run lands where your team works.

### FAQ

#### What does this actor read?

The same data coles.com.au loads in your browser to fill its search, category, specials, product and store pages, as anyone sees it without logging in. It does not log in, add anything to a trolley or read account data.

#### Do Coles prices really differ by store?

Yes, for some products: was prices, specials and stock differ, and some products are not ranged at every store. In our test the same Tim Tam pack had a was price of $6.42 in Karratha and $6.00 in Melbourne, and 279 against 557 packs in stock. Without stores you get Coles' default online store (store 7674).

#### How many products can I get?

Up to 30,000 per list and store. The full catalogue returned 24,926 products for one store in our test (18 departments, duplicates across departments removed). Coles serves the first 5,000 products of any one list; the actor reads bigger categories and the full specials list part by part. A keyword search is not split: narrow it if it has more than 5,000 results.

#### Why do some rows have no price?

Coles still lists some products it does not sell online at the moment; they come back with `in_stock: false` and no price. 31 of 6,725 rows in our test.

#### How does monitor mode know what changed?

It keeps the last price, was price, special and stock of every product it delivered, per store, in a key value store named after `monitorName` in your Apify account. Each run compares against it and saves the new values. Use a different `monitorName` for each watch list.

#### How long does a run take?

In our tests: 7 seconds for the "Try it" input, 90 seconds for the 1,805 half price specials, 165 seconds for 6,725 products from two departments, and 41 seconds for 96 products with `includeDetails`. The default time limit is 3,600 seconds; the actor stops before it and keeps every row.

#### Do I need an account, cookies or a proxy?

No. The actor uses Apify Proxy, included in the price. Coles sometimes answers a datacenter IP with a bot check page; such a page is retried on a new IP, and a page refused twice gets a last try on an Australian residential IP. When most datacenter calls are refused, the actor goes to residential IPs first until datacenter IPs are answered again. All at our cost.

#### Which formats can I download?

JSON, CSV, Excel, XML, RSS and HTML from the run's Storage tab or through the API. The dataset has four ready views: Products, Prices and stock, Barcode and nutrition, and Price changes. In CSV and Excel, `nutrition` is flattened into columns such as `nutrition/per_100g/Protein`.

#### Can I use it from Claude, ChatGPT or Cursor (MCP)?

Yes, through Apify's MCP server. Connector URL: https://mcp.apify.com/?tools=themineworks/coles-scraper

- Claude: Settings > Connectors > Add custom connector, paste the URL, sign in with Apify.
- ChatGPT: turn on developer mode, add an MCP connector with the URL, sign in with Apify.
- Cursor or VS Code: add it as an HTTP MCP server with that URL.
- Claude Code: `claude mcp add -t http coles-scraper "https://mcp.apify.com/?tools=themineworks/coles-scraper"`

#### Is it legal to scrape Coles?

The actor reads public product and price data that Coles shows to anyone without logging in, and no personal data. Coles' robots.txt asks crawlers to stay away from its `/search/` pages; the actor does not load those pages, it reads the search data the site loads for them, with the keyword you give. Decide for yourself whether that suits your use. You are responsible for how you use the data and for following the site's terms and the law. This is general information, not legal advice. Coles is a trademark of Coles Group; this actor is independent and not affiliated with it.

### Integrations

- **Google Sheets**: send each run's products to a sheet with Apify's Google Sheets integration; one row per product fits a sheet as is.
- **Make, Zapier and n8n**: start a run and read its dataset with the Apify apps and nodes, for example "Coles price drops on our watch list every morning to Slack".
- **Webhooks**: have Apify call your URL when a run succeeds, then fetch the dataset.
- **API and SDKs**: run it from Python or JavaScript with the Apify client, or with a plain HTTP call (see "Copy to your AI assistant" above).
- **MCP clients**: Claude, ChatGPT, Cursor and VS Code can run it as a tool through the connector URL in the FAQ.

### More from The Mine Works

**E-commerce and marketplaces**

- [Ozon.ru Scraper](https://apify.com/themineworks/ozon-product-search?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [⭐ Amazon Reviews Scraper](https://apify.com/themineworks/amazon-reviews?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Amazon Product Scraper](https://apify.com/themineworks/amazon-products?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Etsy Listings Scraper](https://apify.com/themineworks/etsy-search-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [AliExpress Scraper](https://apify.com/themineworks/aliexpress-products?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Kleinanzeigen.de Scraper](https://apify.com/themineworks/kleinanzeigen-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Carsales.com.au Scraper](https://apify.com/themineworks/carsales-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [eBay Product Listings Scraper](https://apify.com/themineworks/ebay-search-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Shopify Store Scraper](https://apify.com/themineworks/shopify-store-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [🛒 TikTok Shop Scraper](https://apify.com/themineworks/tiktok-shop-products?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Walmart Product & Price Scraper](https://apify.com/themineworks/walmart-product-price-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Vinted Scraper](https://apify.com/themineworks/vinted-listings-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

**Social media and video**

- [Threads Scraper](https://apify.com/themineworks/threads-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Reddit Scraper](https://apify.com/themineworks/reddit-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Threads Search Scraper](https://apify.com/themineworks/threads-search-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Instagram Profile Scraper](https://apify.com/themineworks/instagram-profile-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

**Leads and business directories**

- [B2B Leads Finder](https://apify.com/themineworks/b2b-leads-finder?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Skip Trace Lookup](https://apify.com/themineworks/skip-trace-lookup?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Google Maps Email Scraper](https://apify.com/themineworks/maps-leads?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [2GIS Places Scraper](https://apify.com/themineworks/2gis-places-search?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

**Marketing, SEO and reviews**

- [Facebook Ad Library Scraper](https://apify.com/themineworks/meta-ad-library-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Google Ads Transparency Scraper](https://apify.com/themineworks/google-ads-transparency?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Similarweb Scraper](https://apify.com/themineworks/similarweb-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Google News Scraper](https://apify.com/themineworks/google-news?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

**LinkedIn**

- [LinkedIn Company Scraper](https://apify.com/themineworks/linkedin-company-details?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [LinkedIn Post Scraper](https://apify.com/themineworks/linkedin-post-search?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [LinkedIn Employees Scraper](https://apify.com/themineworks/linkedin-employees?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [LinkedIn Profile Scraper](https://apify.com/themineworks/linkedin-profile-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

**Real estate**

- [Zillow Rentals Scraper](https://apify.com/themineworks/zillow-rental-listings?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Zillow Sold Comps Scraper](https://apify.com/themineworks/zillow-recently-sold?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [India Real Estate MCP](https://apify.com/themineworks/india-real-estate-mcp?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Housing.com Scraper](https://apify.com/themineworks/housing-com-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

**Science, health and government data**

- [Academic Research MCP](https://apify.com/themineworks/academic-research-mcp?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [CourtListener Scraper](https://apify.com/themineworks/courtlistener-court-records?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Socrata Open Data Scraper](https://apify.com/themineworks/socrata-open-data?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [OpenAlex Scraper](https://apify.com/themineworks/openalex-scholarly-works?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

**Jobs and hiring**

- [Foundit Monster India Jobs](https://apify.com/themineworks/foundit-jobs-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Hirist Jobs Scraper](https://apify.com/themineworks/hirist-jobs-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [India Jobs MCP](https://apify.com/themineworks/india-jobs-mcp?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Naukri Jobs Scraper](https://apify.com/themineworks/naukri-jobs?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

**Company and business data**

- [Company Domain Finder](https://apify.com/themineworks/company-domain-finder?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [GST Taxpayer Lookup](https://apify.com/themineworks/gst-taxpayer-lookup?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Company KYB Resolver](https://apify.com/themineworks/company-identity-resolver?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [SEC EDGAR Filings Scraper](https://apify.com/themineworks/sec-edgar-filings?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

**Food and local services**

- [NoBroker Scraper](https://apify.com/themineworks/nobroker-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Swiggy Restaurant Scraper](https://apify.com/themineworks/swiggy-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Zomato Scraper](https://apify.com/themineworks/zomato-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

**Developer and AI tools**

- [Website to Markdown Crawler](https://apify.com/themineworks/rag-crawler?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [GitHub Skill Finder](https://apify.com/themineworks/github-skill-discovery?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [GitHub Repo Scraper](https://apify.com/themineworks/github-repo-intelligence?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [GitHub Trending Scraper](https://apify.com/themineworks/github-trending-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

**More tools**

- [G2 Reviews Scraper](https://apify.com/themineworks/g2-reviews-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Naver Blog Scraper](https://apify.com/themineworks/naver-blog-posts-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [WeChat Article Scraper 微信公众号文章](https://apify.com/themineworks/wechat-article-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)
- [Taobao Products Scraper 淘宝 天猫](https://apify.com/themineworks/taobao-products-scraper?fpr=ymnoit\&utm_source=apify-readme\&utm_medium=referral)

### Support

Found a list that returns fewer products than the site, or a field that comes back empty? Open an issue in the Issues tab with the input and the run ID, and we will look at it. For a field you need or a new source, email dmineworks@gmail.com.

*Search Coles Australia by keyword, category, specials or product link and get every product back as one row, with price, was price, half price and multi buy offers, unit price per kg or litre, stock by store and, on request, barcode and nutrition, no login.*

# Actor input Schema

## `searchQueries` (type: `array`):

Products as you would type them in the coles.com.au search box, one per line. Example: milk, coffee beans, nappies. Each keyword reads Coles' search results, 48 per page, up to Max products per list. Any Coles link (product, category, specials, search) works here too. Up to 100 searches per run.

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

Coles categories by name (Milk, Dairy, Eggs & Fridge, Soft Drinks), slug path (dairy-eggs-fridge/milk) or link (https://www.coles.com.au/browse/dairy-eggs-fridge/milk). A department includes its categories and aisles. Write all to read every department.

## `specials` (type: `string`):

Read Coles' specials list: every product on special, half price only, multi buy only, or online only specials. Coles changes its specials on Wednesday.

## `productUrls` (type: `array`):

Coles product links (https://www.coles.com.au/product/coles-full-cream-milk-3l-8150288) or product ids (8150288), 24 per call. Each comes with barcode, ingredients, allergens, nutrition and all images (stock quantity comes on list rows only). Built for one record at a time from Clay, n8n or an AI agent, and for watch lists.

## `storeIds` (type: `array`):

Coles prices, was prices and stock differ by store. Give store ids, the number at the end of a store page link (313 in https://www.coles.com.au/find-stores/coles/wa/karratha-313), or the store links themselves. Every list and product is read once per store and each row carries the store. Up to 50 stores per run, store ids and postcodes together. Empty: Coles' default online store.

## `postcodes` (type: `array`):

Australian postcodes, for example 2000 or 6714. Each one uses the nearest Coles supermarket that sells online (a store without an online range is skipped for the next nearest).

## `fullCatalogue` (type: `boolean`):

On: every Coles department (24,926 products for one store in our test). Max products per list does not limit it; use the run's max cost to cap the spend.

## `maxItems` (type: `integer`):

The most products to return for each keyword, category or specials list, per store, 1 to 30,000. Product links are not limited by this. Example: 500.

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

Order of the results, as on coles.com.au. Empty: relevance for keywords, name A to Z for categories and specials (stable between runs, so long lists come back complete).

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

On: the barcode (GTIN), ingredients, allergens, dietary and storage text, nutrition panel, country of origin and all images are added to the rows of keyword, category and specials lists, one extra call per 24 products. Product links always come with these. No extra charge.

## `includeSponsored` (type: `boolean`):

Coles mixes up to 9 paid placements into the first page of a keyword or category. On: they are kept and marked is_sponsored. Off: they are left out and not charged.

## `monitorMode` (type: `boolean`):

On: the actor remembers the last price of every product it delivered (per store, under the monitor name) and returns only products whose price or was price changed, with previous_price, price_change and price_change_percent, plus new products. Unchanged products are not delivered and not charged. Run it on a schedule with the same input.

## `monitorName` (type: `string`):

Keeps separate price memories for separate watch lists, for example dairy-wa. Letters, numbers and dashes. Only used in monitor mode.

## `monitorWatch` (type: `string`):

Price: price and was price only. All: also a special starting, ending or changing its offer, and a product going in or out of stock.

## `includeNewProducts` (type: `boolean`):

On: products the monitor has not seen before are returned with change_type new (on the first run, that is every product). Off: they are saved as the baseline and not returned or charged, so the first run costs nothing per product.

## `residentialRetry` (type: `boolean`):

Coles sometimes answers datacenter IPs with a bot check page. On: a page refused twice gets a last try on an Australian residential IP, and while most datacenter calls are refused the actor goes to residential IPs first (capped per run, at no extra cost to you). Off: datacenter IPs only, and refused pages are skipped.

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

Apify datacenter proxy by default, which Coles answered on most calls in our tests.

## Actor input object example

```json
{
  "searchQueries": [
    "milk"
  ],
  "specials": "none",
  "fullCatalogue": false,
  "maxItems": 30,
  "includeDetails": false,
  "includeSponsored": true,
  "monitorMode": false,
  "monitorName": "default",
  "monitorWatch": "price",
  "includeNewProducts": true,
  "residentialRetry": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

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

No description

# 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 = {
    "searchQueries": [
        "milk"
    ],
    "maxItems": 30,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("themineworks/coles-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 = {
    "searchQueries": ["milk"],
    "maxItems": 30,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("themineworks/coles-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 '{
  "searchQueries": [
    "milk"
  ],
  "maxItems": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call themineworks/coles-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,themineworks/coles-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/37fxb2VZqudCE2NKP/builds/XeWx0EQEPuKmHRlZv/openapi.json
