Coles Australia Scraper - Prices, Specials, Stock & History
Pricing
from $0.50 / 1,000 products
Coles Australia Scraper - Prices, Specials, Stock & History
Coles AU prices, specials and stock for any of ~878 stores (by id, postcode or all), ~27k products, with price history nobody else keeps: previous price, 30-day low, 90-day average and a real-discount check. Barcodes, nutrition, allergens, store directory. Nightly cache, so runs don't fail.
Pricing
from $0.50 / 1,000 products
Rating
0.0
(0)
Developer
Piotr Zimniak
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 hours ago
Last modified
Categories
Share
Independent tool, not affiliated with or endorsed by Coles Group. It reads only public product, price and stock data.
Get prices, unit prices, specials, stock levels for any Coles store, barcodes and full product details (ingredients, allergens, nutrition, country of origin) from coles.com.au as JSON, CSV, Excel or via API. It is the only Coles scraper on the Store that keeps price history (September 2026): the previous price and when it changed, the lowest price in 30 days, the 90-day average, and whether a "special" beats that history.
Why this one
- Runs don't fail. Results come from a catalogue we refresh every night, so a run does not depend on Coles answering at that moment: you always get the latest data, in seconds. See Reliability.
- Any store, or all of them. Prices, stock and aisle for the Coles stores you choose, by store id, by postcode (every store in it) or all ~878 stores, each store as its own rows. Plus the full store directory with addresses and opening hours.
- Price history for every product. Previous price, when it changed, lowest price in 30 days, 90-day average, and a check whether a "special" is a genuine discount. Tracking since 27 September 2026, updated every night; see Price history.
- Barcodes and nutrition at no extra cost for products already in our database;
fetchFullDetailsfills in the rest. - The whole catalogue in one run. Every product Coles sells online (~27k), straight from the nightly snapshot.
- Clean data. Unit prices normalised to per kg, per litre and per item; multi-buy offers as text ("Buy 2 for $9.40"); sponsored duplicates removed.
- Pay for results, not for runs. $0.80 per 1,000 products on the Free plan, down to $0.50, store rows included; the start fee is $0.00005 (a twentieth of a cent). See Pricing.
- See it live. Last night's price moves, specials and the Coles store finder: crawlplant.com/coles-au.
What can you use it for?
- Price monitoring: shelf and unit prices of the products you care about, on a schedule.
- Store-level retail analytics: compare prices, stock and availability across Coles stores and regions.
- Deal hunting and consumer research: half-price and multi-buy specials with a check on whether the discount is real.
- Price-change alerts: products whose price changed since your last run, sent to email, Slack or Sheets.
- Basket and store comparison: barcodes and per-kg prices make matching with other supermarkets straightforward (see our Woolworths Australia Scraper, same output format).
- Nutrition and allergen apps: filter by dietary statement, allergens, sugar or protein.
- AI agents: a fast, well-described tool for "find me the cheapest…" style questions (see Use with AI agents).
Quick start
- Click Try for free (or Start), keep the default input (search for
milk, 100 products) and press Start. It finishes in seconds and costs $0.08 on the Free plan. - Open the Output tab: a table of products with prices, unit prices, specials and stock. Switch views to Product details or Deals check, or export as JSON, CSV or Excel.
- Change the input using one of the ready-to-use examples below, and save it as a task to reuse or schedule it.
Modes
| Mode | What you give it | What you get |
|---|---|---|
search (default) | queries: keywords | matching products, like the site's search |
category | categoryUrls: any coles.com.au/browse/... link (or just dairy-eggs-fridge/milk) | the products in that category |
specials | optional specialsGroups: halfprice, multibuy, onlineonly | current specials (all of them by default) |
barcodes | barcodes: EAN / GTIN codes | those products, looked up in our database (~91% of Coles products have a barcode) |
products | productIds: product ids (the number at the end of a product link) | those exact products, with full details |
urls | urls: any Coles product, search, category or specials link, or a product id | whatever each link shows; sort and specials filters in the link are kept |
catalog | nothing (set maxItems high, e.g. 30000) | the whole catalogue from the nightly snapshot; filters apply |
categories | nothing | departments and categories with their links |
stores | nothing, or storeIds / postcodes | the store directory: address, coordinates, phone, opening hours, click & collect id |
Add storeIds, postcodes or allStores to any product mode (not catalog / categories) to get the prices and stock of those stores.
Ready-to-use examples
Paste any of these into the JSON tab of the input (or send them through the API).
1. Price check for a shopping list: the exact products you buy, by product id.
{ "mode": "products", "productIds": ["8150288", "439693", "7667368"] }
2. Prices and stock in specific stores: one row per product per store.
{ "queries": ["tim tam"], "storeIds": ["313", "7689", "584"], "maxItems": 10 }
3. Cheapest coffee per kg: a search sorted by unit price, within a price range.
{ "queries": ["coffee beans"], "sortBy": "unit_price_asc", "minPrice": 5, "maxPrice": 40, "maxItems": 50 }
4. Everything in a category, cheapest first:
{ "mode": "category", "categoryUrls": ["https://www.coles.com.au/browse/dairy-eggs-fridge/milk"], "sortBy": "price_asc", "maxItems": 500 }
5. This week's half-price specials:
{ "mode": "specials", "specialsGroups": ["halfprice"], "maxItems": 2000 }
6. New specials only, every Wednesday: schedule this weekly to get what just went on special.
{ "mode": "specials", "onlyNewSpecials": true, "maxItems": 5000 }
7. Price-drop alerts since your last run: schedule it daily; each run returns only products whose price changed.
{ "mode": "products", "productIds": ["8150288", "439693", "7667368"], "changedSince": "last-run" }
8. Best sellers on special in a department:
{ "mode": "category", "categoryUrls": ["pantry"], "sortBy": "best_sellers", "specialsOnly": true, "maxItems": 100 }
9. Allergy-safe: no peanuts or tree nuts, with full details:
{ "queries": ["muesli bars"], "excludeAllergens": ["Peanut", "Tree Nut"], "fetchFullDetails": true, "maxItems": 50 }
10. High-protein yoghurt (at least 8 g per 100 g):
{ "queries": ["yoghurt"], "minProteinPer100g": 8, "fetchFullDetails": true, "maxItems": 100 }
11. The whole catalogue (analytics, BI, price comparison sites): served from the nightly snapshot in seconds.
{ "mode": "catalog", "maxItems": 30000 }
12. New products this week:
{ "mode": "catalog", "onlyNew": true, "maxItems": 30000 }
13. 90-day price history for a few products:
{ "mode": "products", "productIds": ["8150288", "439693"], "priceHistoryDays": 90 }
14. Links straight from the browser:
{ "mode": "urls", "urls": ["https://www.coles.com.au/product/coles-full-cream-milk-3l-8150288","https://www.coles.com.au/search/products?q=tim%20tam&sortBy=priceAscending","https://www.coles.com.au/on-special?filter_Special=multibuy"] }
15. Your local Coles by postcode: every Coles store in each postcode, each as its own rows.
{ "queries": ["tim tam"], "postcodes": ["2000", "3000", "4000"], "maxItems": 10 }
16. One product in every Coles store (price and stock map of Australia):
{ "mode": "products", "productIds": ["8150288"], "allStores": true }
17. The store directory: every Coles store with address, coordinates and opening hours.
{ "mode": "stores", "maxItems": 1000 }
18. Products by barcode (EAN / GTIN, e.g. from a scanner or another store's data):
{ "mode": "barcodes", "barcodes": ["9300601186945", "9310072034485"] }
19. This week's biggest discounts, half price and better, biggest first:
{ "mode": "specials", "minDiscountPercent": 50, "sortBy": "discount_desc", "maxItems": 3000 }
20. Daily watch of a brand, including products that were delisted:
{ "mode": "catalog", "brands": ["Arnott's"], "changedSince": "last-run", "includeDisappeared": true, "maxItems": 30000 }
How to…
Scrape Coles half-price specials
Use example 5 (mode: specials, specialsGroups: ["halfprice"]), or multibuy / onlineonly for the other special types.
Add minDiscountPercent: 40 to keep only big discounts, or use example 19 to rank them biggest first.
Get this week's Coles catalogue as data
The weekly catalogue changes on Wednesday. { "mode": "specials", "maxItems": 10000 } returns every product on special
right now, with shelf price, was price, special type, multi-buy offer text and unit price. Schedule it every Wednesday
morning (Sydney time), add postcodes to see it at your own stores, or use example 6 to get only what went on special
this week. This is the catalogue's products as data, not the printed PDF.
Check if a Coles special is a real discount
Every product on special has discountCheck.verdict: genuine means the "was" price was really charged for at least 28 of
the 90 days before the special; questionable means it wasn't. The verdict is given once a product has 28 days of price
history (see Price history).
Compare Coles prices and stock across stores
Add storeIds, postcodes or allStores to any product mode (examples 2, 15, 16). Each product comes once per store
with that store's price, inStock, availableQuantity and aisle.
Get every Coles store location and opening hours
mode: stores (example 17) returns every Coles store with address, coordinates, phone, trading and holiday hours.
Look up Coles products by barcode
mode: barcodes (example 18) with EAN / GTIN codes from the pack or from another store's data.
Get Coles prices per kg or per litre
Every product has pricePerKg, pricePerLitre or pricePerItem. Sort a search by unit price with
sortBy: unit_price_asc (example 3).
Export the whole Coles catalogue
mode: catalog with maxItems: 30000 (example 11) returns every product Coles sells online from the nightly snapshot.
Input options
Stores (combine freely; each store gets its own rows):
storeIds: Coles store ids, the number at the end of a store page link, e.g.313incoles.com.au/find-stores/coles/wa/karratha-313(or run modestoresto list them all).postcodes: up to 500 Australian postcodes; every Coles store in each postcode (the run log lists them). A postcode without a Coles gives no rows; the warnings name its nearest store and distance, so you can add it tostoreIds.maxItemsapplies per store.allStores: every Coles store (~878).maxItemsapplies per store, so keep it small.
Without them you get Coles' default online store (id 7674), which is the one our nightly catalogue and price history cover.
Store prices come from our nightly read of every product in every Coles store, so even allStores answers in minutes; a store
not read since this week's specials change (Wednesday) is fetched live.
Filters and sorting (all modes):
sortBy:relevance,price_asc,price_desc,unit_price_asc,best_sellers,discount_desc. Sorting is done by Coles before paging (discount_descre-sorts the collected results by % off, so combine it withspecialsOnlyor specials mode and a highmaxItems), so you get the true cheapest products, not just a re-ordered first page.specialsOnly(filtered by Coles, no wasted pages),inStockOnly,minPrice/maxPrice,excludeCategories(department names or slugs;tobaccoby default),brands(exact brand names),minDiscountPercent(e.g. 40 = only specials at least 40% below the was-price; multi-buy offers never match).specialsGroups(specials mode):halfprice,multibuy,onlineonly. Empty = every special.
Health and nutrition: dietary (e.g. ["Gluten Free"], all required), excludeAllergens (e.g. ["Peanut", "Milk"]),
maxSugarPer100g, minProteinPer100g. These use product details: from our database when we have them, or from the product
page with fetchFullDetails. Products without the data a filter needs are left out, so you never get a product we can't confirm.
Price history (from our shared daily price database, default online store):
changedSince: only products whose price changed since a date (2026-09-01) or since your previous run (last-run).includeDisappeared(withchangedSince: "last-run"): also returns rows withtype: "disappeared"for products your previous run returned that are gone now (delisted, or no longer matching your filters), with their last price and when they were last seen.onlyNewSpecials: only products that went on special in the last 7 days (Coles specials change on Wednesdays).onlyNew: only products that appeared at Coles in the last 7 days.priceHistoryDays: add the list of price changes from the last N days.
Other options:
maxItems: products per query / category / link and store, after filters (default 100). For specials, products and catalog it applies per run and store.maxAgeHours: how old our data may be (default 36; anything read before this week's specials change on Wednesday is fetched live;0= always fetch live).fetchFullDetails: add barcode, ingredients, allergens, dietary statement, nutrition panel, country of origin and storage from the product page, for products that don't have them yet. It takes one extra request per product and is charged per product.includeRaw: add the original Coles payload (every field, including ones we don't map).
Example output
{"store": "coles","productId": "8150288","barcode": "9300601186945","name": "Coles Full Cream Milk","brand": "Coles","size": "3L","url": "https://www.coles.com.au/product/coles-full-cream-milk-3l-8150288","imageUrl": "https://cdn.productimages.coles.com.au/productimages/8/8150288.jpg","price": 4.95,"wasPrice": 4.95,"unitPrice": 1.65,"unitMeasure": "1L","pricePerLitre": 1.65,"isOnSpecial": false,"specialType": null,"offerDescription": null,"inStock": true,"storeId": "584","availableQuantity": 438,"purchaseLimit": 20,"aisle": null,"categoryPath": ["Dairy, Eggs & Fridge", "Milk", "Full Cream Milk"],"ingredients": "Homogenised and Pasteurised Full Cream Milk.","allergens": { "contains": ["Milk"], "mayContain": [] },"nutrition": {"servingSize": "250mL","servingsPerPack": "12.00","items": [{ "name": "Energy (kJ)", "per100": "258 kJ", "perServing": "646 kJ" }, { "name": "Protein", "per100": "3.4 g", "perServing": "8.5 g" }]},"dietaryTags": ["Source of Calcium"],"countryOfOrigin": "Australian Milk","storage": "Keep this way up,Keep refrigerated. Store at or below 5°C","previousPrice": null,"priceChangedAt": null,"lowestPrice30d": 4.95,"averagePrice90d": null,"discountCheck": null,"scrapedAt": "2026-09-27T15:45:14.223Z","source": "live"}
Output fields
| Group | Fields |
|---|---|
| Identity | store, productId, barcode (GTIN), name, brand, size, url, imageUrl, images, categoryPath |
| Price | price, wasPrice, unitPrice + unitMeasure, pricePerKg, pricePerLitre, pricePerItem |
| Store & stock | storeId, storeName, storeSuburb, storeState, storePostcode, inStock, availableQuantity, purchaseLimit, aisle |
Store directory (mode stores) | storeId, name, brand, address, suburb, state, postcode, latitude, longitude, phone, tradingHours, holidayHours, collectionPointId, url |
| Specials | isOnSpecial, specialType (Half Price, Multi Buy, Online Special, Special), offerDescription, specialStartedAt, discountCheck, specialCycle |
| History | previousPrice, priceChangedAt, lowestPrice30d, averagePrice90d, firstSeenAt, priceHistory (with priceHistoryDays) |
| Product details | description, ingredients, allergens, nutrition, dietaryTags, storage, countryOfOrigin |
| Freshness | scrapedAt, source (cache or live) |
All prices are in AUD, as numbers. wasPrice equals price when nothing is discounted (multi-buy offers have no was-price;
see offerDescription). Detail fields are null (or empty lists) until we have the product page for a product.
Deal check for specials: discountCheck.verdict is:
genuinewhen the "was" price was actually charged for at least 28 of the 90 days before the special;questionablewhen it was not (for example, when the price was raised shortly before the "discount");insufficient-historywhen the product has less than 28 days of price history.
specialCycle shows how often a product goes on special and when the next one is expected, once we have seen 3 of its specials.
Price alerts in 5 minutes
- Save a task with the input you want to watch (examples 6 and 7 above are good starting points).
- Add a schedule (for example every Wednesday morning, when specials change, or daily for price drops).
- In the task's Integrations tab, send results to email, Slack, Google Sheets, Zapier, Make, n8n or a webhook.
With changedSince: "last-run", each run returns only what changed since the previous one, so quiet days cost nothing.
Run it through the API
cURL (runs synchronously and returns the items):
curl -X POST "https://api.apify.com/v2/acts/crawlplant~coles-au/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"queries": ["milk"], "maxItems": 20}'
JavaScript (npm install apify-client):
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('crawlplant/coles-au').call({ mode: 'specials', specialsGroups: ['halfprice'], maxItems: 200 });const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.map((p) => `${p.name}: $${p.price} (was $${p.wasPrice})`));
Python (pip install apify-client):
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("crawlplant/coles-au").call(run_input={"queries": ["coffee"], "sortBy": "unit_price_asc", "maxItems": 20})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["name"], item["pricePerKg"])
Use with AI agents
The Actor works as a tool in the Apify MCP server: Claude, ChatGPT, Cursor, VS Code, LangChain, CrewAI, OpenAI Agents and others. Small queries are answered from the cache in seconds, and every output field is described, so agents understand the data without extra prompting.
To give an assistant only this tool, use this server URL:
https://mcp.apify.com?tools=crawlplant/coles-au
Example for Claude Desktop (claude_desktop_config.json):
{ "mcpServers": { "coles": { "command": "npx", "args": ["mcp-remote", "https://mcp.apify.com?tools=crawlplant/coles-au"] } } }
Try prompts like "find the cheapest olive oil per litre at Coles", "which Coles half-price specials are genuine this week?" or "is Tim Tam in stock at Coles Karratha (store 313)?".
Pricing
Pay per result: you pay for the products returned, and platform usage (compute, proxies) is included.
| Event | Free plan | Starter | Scale | Business and up |
|---|---|---|---|---|
| Product (per 1,000 results) | $0.80 | $0.70 | $0.60 | $0.50 |
Full product details (per 1,000, only with fetchFullDetails) | $0.40 | $0.35 | $0.30 | $0.25 |
| Actor start (per run) | $0.00005 | $0.00005 | $0.00005 | $0.00005 |
Store rows count as products (3 stores × 10 products = 30 results), and each store in mode stores counts as one result. Barcodes and details we already have, price history and deal
checks are included in the product price. A failed or empty run costs only the start fee.
| Example on the Free plan | Results | Cost |
|---|---|---|
Default run: search milk | 100 | $0.08 |
tim tam in the stores of 3 postcodes, 10 each | ~30-60 | $0.02-0.05 |
| One product in every Coles store | ~878 | $0.70 |
| Store directory | ~878 | $0.70 |
| Whole catalogue | ~27,000 | ~$21.60 |
Daily watch with changedSince: "last-run" | only the changes | often $0.00 |
Set a maximum cost per run in the run options to stop a large run at your budget.
Compared with other Coles scrapers (Free plan prices on the Apify Store, 27 September 2026): the most-used one charges $1.00 per 1,000 products plus $0.008 per run; the others charge $1.49-10.00 per 1,000, several with a start fee of $0.005-0.10 and extra charges for details. None of them includes price history.
Reliability
- Most queries are answered from our nightly catalogue in seconds, so a run doesn't depend on Coles answering at that moment. Every Coles store's prices are read every night too; anything newer is fetched live through Australian proxies, included in the price.
- If a live request doesn't come through, the run still finishes with everything else and a note in its summary. An empty run costs only the start fee.
- Automated checks test the Actor, the data and its freshness every 3 hours, around the clock.
Price history
We have tracked every Coles online price since 27 September 2026, and every night adds each change. Every product row
carries previousPrice, priceChangedAt, lowestPrice30d and averagePrice90d; priceHistoryDays adds the full list of
changes. discountCheck rates a special once the product has 28 days of history, and onlyNew / onlyNewSpecials
look at the last 7 days.
Data freshness
Every item has scrapedAt (when the price was read from Coles) and source:
cache: from our database, no older than yourmaxAgeHours. The whole catalogue is refreshed every night (Sydney time).live: fetched from Coles during your run.
Store rows from our nightly store read carry that read's time in scrapedAt; their inStock is the store's online
availability at that time.
If a live request doesn't come through, the run still finishes with the latest cached data and a note in the run's OUTPUT record.
Troubleshooting
- Fewer results than expected: filters (price, dietary, allergens) leave out products that don't match or have no data.
The
OUTPUTrecord in the run's key-value store lists any warnings, e.g. when up to 30 pages were scanned without enough matches. - Health filters return few products: they need product details. Add
"fetchFullDetails": truefor complete results. - "category not found": run mode
categoriesto get the exact category links, then paste one intocategoryUrls. previousPriceisnull: we have not seen that product's price change since we started tracking it.- No history fields on store rows: price history covers Coles' default online store only.
onlyNew/onlyNewSpecialsreturn nothing with a warning: these need a week of tracking history; the warning shows the date they start working.- A product id isn't returned: the product no longer exists; it is listed in the run warnings and not charged.
FAQ
Do Coles prices and stock differ by store?
Yes, for some products. Without storeIds / postcodes / allStores you get the default online prices Coles shows before
you choose a store or postcode. With them, the prices and stock of those stores (and the aisle, when read live), each store
as its own rows.
How much does it cost to scrape Coles?
$0.80 per 1,000 products on the Free plan, down to $0.50 on higher plans, plus $0.00005 per run. The default run costs $0.08. See Pricing.
Is a Coles special a real discount?
Check discountCheck.verdict on the product: genuine or questionable, based on what the product really cost before
the special. See Check if a Coles special is a real discount.
When do Coles specials change?
Every Wednesday. Schedule a specials run on Wednesday morning (Sydney time) to track each new week.
Which stores does a postcode give?
The stores whose address is in that postcode, from our weekly store directory. For a postcode without a Coles, the warning's nearest store is measured from the centre of the postcode (ABS Postal Areas), as the crow flies.
Why are some products missing price?
The product is currently unavailable at that store.
How is this different from other Coles scrapers?
Runs finish reliably, results are served from a nightly snapshot in seconds, and every product carries price history, a genuine-discount check and normalised unit prices. Barcodes and nutrition come free when we already have them, and there is a full-catalogue mode. See Pricing for a price comparison.
Is it legal to scrape Coles?
The Actor reads only public product, price and stock information that anyone can see without logging in. It does not collect personal data or reviews. It is not affiliated with Coles Group.
Good to know
- With filters, up to 30 result pages (~1,400 products) are scanned per query or category and store; the run says so when that cap is hit.
- Coles has no sort by name; use a price sort for exact, repeatable ordering.
- Tobacco is excluded by default.
Run summary
The key-value store record OUTPUT shows items returned (cache vs live), invalid records skipped, request statistics,
the proxy route used, extra events charged and any warnings.
Data sources
Product, price, stock and store data: public pages of coles.com.au. Postcode locations: Australian Bureau of Statistics, Postal Areas (ASGS Edition 3), CC BY 4.0.
Privacy
The Actor only reads public product pages and does not collect personal data. To decide which features to build next, each run sends the developer usage statistics: the mode, which options were used (e.g. "sortBy: price_asc", "specialsOnly: on", "2 stores"), result counts and duration. It never sends your search terms, URLs, product ids, store ids, postcodes, results or any account details. Your Apify account id is replaced on arrival by a one-way keyed hash (the id itself is never stored), used only to count how many different accounts use the Actor.