# Kmart Australia Scraper Lite (`abotapi/kmart-au-scraper-lite`) Actor

Scrape kmart.com.au products and reviews: names, brand, prices, promotions, ratings, reviews, colours, sizes, images, seller, categories, stock, variations and specifications. Search or paste product and category URLs, with sorting and filters.

- **URL**: https://apify.com/abotapi/kmart-au-scraper-lite.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** E-commerce, Developer tools, Automation
- **Security:** Limited permissions
- **Stats:** 1 total users, 1 monthly users, 99.8% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 products

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## Kmart Australia Scraper Lite: Prices, Descriptions and Reviews

Kmart Australia Scraper Lite turns kmart.com.au into a clean product data feed. Search by keyword, browse the Clearance, Catalogue or Online Exclusives collection, or paste product, category and search links, then get one flat record per product: name, canonical title, brand, current price with the was/original price and discount, star rating, full per-review text, Kmart's own product description split into features, specifications, care instructions and safety warnings, images, and every colour/size variation with its own stock status. Reviews attach to each product automatically, and Incremental mode returns only new and changed products, including a variant going in or out of stock, on a recurring schedule.

### Why This Scraper?

- **Two ways to start.** Search by keyword with sorting and facet filters, or paste product, category, search and specials-collection URLs from kmart.com.au. Facet filters carried in a pasted link (for example `?f.Shops=Kmart&f.Shops=Target`) are applied.
- **Specials and discounts.** Browse Kmart's Clearance, Catalogue and Online Exclusives collections, and get the was/original price, saving amount and percent, and on-special flag on every product that is genuinely reduced.
- **Full product copy, structured.** Kmart's own description arrives verbatim, plus the same text split into features, specifications, care instructions, additional info, safety warnings and manual links, so nothing has to be parsed by hand.
- **Products and reviews together.** Each product carries its rating summary plus individual review text, author, date, helpful votes and sub-ratings (Value, Quality).
- **Filters that narrow results.** Brand, colour, category and sort apply to searches and to pasted category, search and specials URLs; the price range, the seller choice and the marketplace exclusion also apply to a single pasted product URL. Third-party marketplace sellers are excluded by default, and **Sellers** picks exactly which sellers you want, for example Kmart and Target without the Officeworks range.
- **Built for schedules, down to your local stores.** Incremental mode returns only new and changed products on recurring runs, or resume one interrupted crawl with a run id. Optionally add per-store stock and Click & Collect availability for the Kmart stores near your postcodes, for every colour and size, or track only the states you pick.
- **Optional export.** Pipe results straight into Notion, Linear, Airtable or Apify through MCP connectors.

### Use Cases

- **Price and discount tracking:** monitor Clearance, Catalogue and Online Exclusives collections to catch genuine markdowns as soon as they appear.
- **Competitor and market research:** compare Kmart's pricing, ranges and stock across categories against other Australian retailers.
- **Catalog and content teams:** pull Kmart's own product copy, features and specifications to populate a comparison site or content feed without re-typing it.
- **Review and reputation analysis:** collect star ratings, review text and sub-ratings to track customer sentiment per product or category.
- **Recurring price-drop alerts:** schedule the actor with Incremental mode and get notified only when a tracked product's price or stock actually changes.
- **Buying from local stores:** see which nearby stores hold each size today and get a row only when a size comes back in stock (or sells out) at one of the 5 stores nearest your postcode.

### Data You Get

> Sample shape: values are illustrative placeholders, not from a live listing.

| Field | Example |
| --- | --- |
| `id` | `"42442370"` |
| `name` | `"Sample Bath Towel"` |
| `title` | `"Sample Brand Sample Bath Towel"` |
| `brand` | `"Sample Brand"` |
| `price` | `8.0` |
| `currentPrice` | `8.0` |
| `wasPrice` | `12.0` |
| `isOnSpecial` | `true` |
| `averageRating` | `4.6` |
| `reviewCount` | `316` |
| `colour` | `"Blue"` |
| `size` | `"One Size"` |
| `seller` | `"kmart"` |
| `isMarketplace` | `false` |
| `inStockNationally` | `true` |
| `url` | `"https://www.kmart.com.au/product/sample-bath-towel-42442370/"` |
| `images` | `["https://assets.kmart.com.au/transform/.../42442370-1", "..."]` |
| `variations` | `[{ "colour": "Blue", "size": "One Size", "price": 12.0, "apn": 9300000000000, "inStock": true, "outOfStockStates": null }]` |
| `description` | `"Sample lead sentence.<br /><br /><strong>Product Details</strong><ul><li><strong>Material:</strong> Cotton</li></ul>"` |
| `descriptionText` | `"Sample lead sentence.\nProduct Details:\n- Material: Cotton"` |
| `features` | `["Sample feature", "Another feature"]` |
| `specifications` | `{ "Dimensions/Size": "135cm (L) x 68cm (W)", "Material": "Cotton" }` |

Every product record also carries `careInstructions`, `additionalInfo`, `warnings` and `manuals`, split from the same description text, plus a `detailSections` view that keeps every heading Kmart publishes, even ones not named above, in the order they were published. An absent section comes back as `null`, never as an empty list or object.

`apn` is the product's barcode (APN, a number), on the product and on each entry in `variations`. Compact rows (`compactUpdates`) carry it too: `UPDATED` and `EXPIRED` rows have the product's `apn`, and every `variantChanges` and `deliveryChanges` entry has the variant's `apn` next to its `variationId`.

Each entry in `variations` also carries `inStock` and `outOfStockStates`, Kmart's own per-state stock flag for that exact colour/size combination, straight from the same product card (no extra request). `outOfStockStates` lists the Australian states/territories where Kmart flags the variant out of stock for online delivery (e.g. `["NSW", "VIC"]`); a state that is flagged answers "no home delivery" for a postcode in that state, and a state that is not flagged answers "deliverable". It is `null` when Kmart flags no state at all. `inStock` is `false` only once all 8 states are flagged. Every product has at least one entry in `variations` (a single-size item has one, with the product's own number as its id). These are state-wide online flags: a state missing from the list does not prove that any particular store has the item on its shelf. For shelf stock at your local stores, use **Store postcodes** (see "Store availability near your postcode" under Output Example).

Reviews and review statistics attach to the same product record: `reviews` is an array of `{ rating, title, content, author, createdAt, verifiedBuyer, votesUp, votesDown, subRatings }`, and `reviewStats` carries the `totalReviews`, `averageScore`, `starDistribution` and `subRatings` summary; when Fetch reviews is off (or Max reviews is 0), both come back `null`, but a product with no reviews returns `reviews: []` and a `reviewStats` with `totalReviews: 0`.

### How to Use

1. Pick a **mode**: `search` (keywords, with optional sort, filters and a specials collection), `url` (paste product, category, search or specials-collection links) or `basket` (check the exact size and quantity of each basket line at your stores, see [Basket check](#basket-check-exact-size-and-quantity-at-your-stores)).
2. In search mode, add one or more search terms, or leave them empty and pick a **Specials collection** to browse Clearance, Catalogue, Online Exclusives or the current Weekly catalogues instead.
3. Set **Max products** to control run size and cost, and turn **Fetch reviews** on or off.
4. Click **Start**, then download the dataset as JSON, CSV or Excel, or read it through the API.

**Search for a keyword:**

```json
{
  "mode": "search",
  "searchTerms": ["towel"],
  "maxItems": 20
}
```

**Search with sorting and filters:**

```json
{
  "mode": "search",
  "searchTerms": ["towel"],
  "sortBy": "price-asc",
  "brand": "Anko",
  "minPrice": 5,
  "maxPrice": 30,
  "maxItems": 25
}
```

**Browse a specials collection (Clearance, Catalogue or Online Exclusives):**

```json
{
  "mode": "search",
  "specialsCategory": "clearance",
  "maxItems": 50
}
```

Weekly catalogues reads the catalogues shown on Kmart's Catalogue page (for example a seasonal catalogue and a toy catalogue, a few hundred products in total) and returns each listed product with the usual fields plus `catalogueOffers`: the catalogue name, its offer dates and the catalogue price. With Incremental mode on, scheduled runs return only products that are new to the catalogues or whose price or stock changed; a product moving to another catalogue does not count as a change on its own. This is different from **Catalogue**, which is Kmart's small fixed catalogue collection in its product search.

Discounted products carry `wasPrice`, `savingsAmount`, `savingsPercent` and `isOnSpecial`. Kmart runs an everyday-low-price model, so a was/original price is populated only when an item is genuinely reduced right now; otherwise those fields are `null` and `isOnSpecial` reflects clearance status instead. A specials collection can also be reached in url mode by pasting its page URL.

**Paste URLs:**

```json
{
  "mode": "url",
  "urls": [
    "https://www.kmart.com.au/search/?searchTerm=towel",
    "https://www.kmart.com.au/product/sample-bath-towel-42442370/"
  ],
  "maxItems": 30
}
```

**Supported URL shapes (URL mode):** department pages (`/toys/`, `/womens/`; `?page=N` starts at that page), specials (`/catalogue/`, `/clearance/`, `/category/online-exclusives/`), brand pages (`/brand/target/`), nested category pages (`/category/home-and-living/home-decor/`), search (`/search/?searchTerm=towel`) and product pages (`/product/<name>-<id>/`, including clothing pages ending in `-s<number>/` such as `/product/everyday-jeans-s161099/`). A bare Kmart product id is also accepted in place of a product URL: `43572342`, or a clothing style id such as `S175824`. A URL that matches none of these, or a product that is no longer listed, is skipped with a warning in the run log. **Max products** applies to pasted product URLs too: set it to `0` (no cap) or to at least the number of products, otherwise the run log warns that the rest were not checked.

**Choose sellers:** kmart.com.au lists products sold by Kmart, Target, Officeworks and marketplace sellers. Set **Sellers** (`sellers`) to the ones you want, for example `"sellers": ["Kmart", "Target"]` to leave out the Officeworks range. Left empty, a run keeps the usual choice: Kmart, Target and Officeworks, plus marketplace sellers when **Include marketplace products** is ticked. When Sellers is set it replaces that tick box (add `Marketplace` to the list to include marketplace sellers). A product sold by more than one seller is one row with one `id`, returned and billed once (its `seller` reads `multiple`), and it is kept when any of its sellers is in your list: with Kmart and Target picked, an item that Kmart and Officeworks both sell stays, and only items that none of your picked sellers sells are left out, before their reviews, store stock or delivery are looked up, so no product event is charged and no platform usage is spent on lookups for them. Sellers applies to searches, specials collections, Weekly catalogues, pasted category, search and specials links, and pasted product links and ids (checked once the product is fetched). A pasted listing link that already carries its own seller filter, such as `?f.Seller=Kmart&f.Seller=Target`, keeps it for that link, and the run log warns when it differs from Sellers; seller values in a link are case-sensitive and repeated once per value. Basket check ignores Sellers.

**Behaviour change:** the `urls` field now has a default (one sample URL per shape above) instead of being empty. A URL-mode run started through the API without a `urls` value now scrapes those sample pages instead of returning nothing; pass `urls` explicitly to control what is scraped.

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/kmart-au-scraper-lite").call(run_input={"mode": "search", "searchTerms": ["towel"]})
for product in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(product["name"], product["price"])
```

JavaScript:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/kmart-au-scraper-lite').call({ mode: 'search', searchTerms: ['towel'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the **Integrations** tab.

#### Resume and recurring updates

- **Resume** (`resumeFromRunId`) continues one interrupted run: paste its run or dataset id and the actor skips every product already collected there, so you don't pay twice. If a run is interrupted (a platform migration, a Resurrect, or a run cut off at its time limit), what it already returned is not returned again: a restarted run skips every product already in its dataset, counts them toward **Max products**, and in Incremental mode puts them into the saved history. If a run stops before it could save its history, the next run of the same search first adds what that run returned to the history, once the earlier run is over according to the platform (aborted, failed or timed out; only while no newer history was saved in between), so those products are not returned, or billed, a second time; if that run's storage cannot be read, the log says so and those products may come back once. Where a run's status cannot be read, its time limit decides instead, so an aborted run is only added once that limit has passed, and a Resurrected run that has not yet returned anything can look finished once its first time limit has passed (the next run may then add its earlier rows to the history while it is still running). A run also stops starting new work about a minute before its time limit, saves its history and summary, and says so in its status message (see "How do I check what a run did?").

- **Incremental mode** (`incrementalMode`) is for scheduling the same search, specials collection or URL set again and again (for example, daily). The actor remembers the previous run of that exact scope by itself, so you never paste a run id. The first run returns everything as `NEW`. Later runs return only `NEW` and `UPDATED` products by default, with `changedFields` listing what changed on an `UPDATED` row; products unchanged since the last run are suppressed unless `emitUnchanged` is on. `EXPIRED` rows are produced only when `emitExpired` is on, and only after a run that scanned the whole tracked scope (not capped by Max products or Max pages, not a resume, not a pasted listing link with `?page=2` or higher, which skips the earlier pages, and not a listing with 10,000 or more results, because Kmart serves at most 10,000 results for one listing and the rest cannot be reached). A product must have been marked `EXPIRED` at least once before it can later be classified `REAPPEARED`, so `REAPPEARED` never appears in a run where `emitExpired` has not previously been turned on. `stateKey` names or deliberately shares a monitoring campaign; left empty, it is derived automatically from the search/filter setup. `ignoreFieldsForChanges` lets you exclude extra top-level fields from change detection if something in your own setup turns out to be noisy; reviews, review stats, the average rating and `groupIds` (Kmart's merchandising-group ids, which change when a product joins or leaves a catalogue or seasonal group without the listing itself changing) are already excluded by default and never trigger `UPDATED`. One-time migration note: the first Incremental run after the release that added `wasPrice`, `savingsAmount` and `savingsPercent` from Kmart's "WAS $x" text, and the extra card fields (`uri`, fulfilment and shipping flags, marketplace badges), treats those newly filled fields on an already-tracked, otherwise unchanged product as `UNCHANGED`, so it is not returned again. A real price or name change on the same product still comes back `UPDATED`. **Coming from the Kmart Australia Scraper?** If you tracked the same State key (or the same search settings) there, pick that scraper's history store (`kmart-com-au-incremental-state`) in "Continue from the Kmart Australia Scraper's history" and the first Lite run continues from that saved history, so you are not given the whole catalogue as NEW again. Your earlier history is only read, never changed, and nothing needs to be copied or run.

- **Start from an existing dataset** (`baselineDatasetId`, optional, Incremental mode only): if you already scraped the catalogue with this Actor, pick that run's dataset in the input form and your first Incremental run returns only products that changed since then, instead of the whole catalogue again. Pick the dataset unedited: it must be this Actor's own product output (a CSV or Excel export, renamed columns or another tool's data is refused, and the run stops before scraping with a message saying why). It is only used while the state key has no saved state; once a run has completed it is ignored. Products in the dataset that are unchanged are not returned or billed; changes since the dataset was made come back as `UPDATED`, new products as `NEW`, and with `emitExpired` on, products no longer on the site as `EXPIRED`. It cannot be combined with Resume from a previous run, and it must be selected from the list (a pasted id may not be readable).

- **Sellers on a scheduled search** (Incremental mode): Sellers is not part of the state key, so a search keeps one saved list whatever seller choice you pick, and adding, changing or removing Sellers never starts a new list. A product the current choice leaves out stays in the saved list but is kept aside: it is not returned, not billed, never marked `EXPIRED`, and its missed-scan count starts again from zero. Once a later choice (or no choice) covers it again it is compared as usual, so an unchanged product stays suppressed and a change is returned and billed once, never again under another choice. A product saved before you used Sellers that shows several sellers (`seller: "multiple"`) does not record which ones: it is compared normally whenever a run sees it, and kept aside once a complete scan under your Sellers does not find it; products seen while Sellers is on also have their sellers noted, so this is needed only once. Two Tasks that run different Sellers on the same search with no `stateKey` share that one saved list (each run then also compares the other's products when it sees them); give each Task its own `stateKey` to keep them apart. Include marketplace products stays part of the state key, as before; while Sellers is set, flipping it continues from the list saved under the other setting. History continued from the Kmart Australia Scraper through the earlier history store is treated the same way: its products have no saved seller list, so a product sold by several sellers is kept aside only once a complete scan under your Sellers does not find it.

- **Change for listings over 10,000 results:** Kmart serves at most 10,000 results for one listing. A run that reaches that limit on a search, category or specials listing now logs a warning and no longer counts as a complete scan, so it never marks products `EXPIRED` from the part it could not reach (before, products past the limit could be reported `EXPIRED`). Narrow the listing, for example with Sellers, to cover it completely.

- Reviews can still be fetched for scanned products in Incremental mode. Suppressed rows consume platform resources but incur no actor event fee.

#### Large categories

With **Check online delivery live** on, the delivery checks take most of a run's time: one check per size and tracked state, at roughly 7 to 9 checks a second, so a category with 25,000 sizes needs about 50 minutes for one state. Set the Task's timeout above products x sizes / 7 seconds, plus a few minutes for the listing pages; more memory does not make the checks faster. A check that never answers is given up after its own time budget (about 25 seconds, the call plus one retry) and is not asked again in that run, so a few permanently unreadable sizes cost seconds, not minutes. With the check on, the run also uses one extra connection session to read the next listing page while the current one is handled. A run that reaches its time limit stops about a minute early, saves its history and says so in its status, and the next run continues normally.

Several overlapping subcategory links in one Task are safe with this version: each link is walked to its own end, and a product listed under two links is returned once. Do not use a parent department link (for example `/womens/`) whose listing is larger than the site's 10,000-result limit: the site stops listing after 10,000 products, so the rest are never reached. Use its subcategory links instead.

### Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step **after** the scrape: the Apify dataset is never changed.

**What gets written to the connector:** a condensed, human-readable **summary** of each product, not the full JSON. Each item becomes one entry with a **title** and its key fields flattened to plain text. The **complete record always stays in the Apify dataset**.

1. Authorize a connector once under **Apify then Settings then Integrations** (Notion, Linear, Airtable, or Apify).
2. Select it in the **"Pipe results into your apps"** input field. If the picker is empty, you haven't authorized a connector yet.
3. For **Notion**, also set `notionParentPageUrl` to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

### Input Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | string | `search` | `search` for keywords (and the specials collection), `url` for pasted links, `basket` for a basket check. |
| `searchTerms` | array | none (prefill: `["towel"]`) | Keywords to search. Search mode only. |
| `specialsCategory` | string | `""` (none) | Optional specials collection: `clearance`, `catalogue`, `online-exclusives`, or `weekly-catalogues` (every product in the current promotional catalogues). Search mode only. |
| `urls` | array | 10 sample URLs, one per supported shape (see URL mode) | Product, department, category, brand, search or specials URLs. URL mode only. |
| `basketItems` | array | none | Basket mode only. One object per basket line: `url` (a product page), `colour` and `size` or `variantId` (variant id or APN) for a product sold in several, and `quantity` (default 1). Up to 50 lines; Max products caps how many are checked. |
| `sortBy` | string | `relevance` | `relevance`, `popular`, `newest`, `price-asc`, `price-desc`. |
| `brand` | string | none | Keep only this brand (exact facet value, e.g. Anko). |
| `colour` | string | none | Keep only this colour (exact facet value). |
| `category` | string | none | Keep only this category (exact facet value). |
| `includeMarketplace` | boolean | `false` | Also keep third-party marketplace sellers' products. By default only the Kmart, Target and Officeworks ranges are returned. |
| `sellers` | array | none | Only products sold by these sellers: any of `Kmart`, `Target`, `Officeworks`, `Marketplace`. A product with several sellers is one row, kept when any of them is picked. Empty = the usual choice above. When set, it replaces `includeMarketplace`. See "Choose sellers" under How to Use. |
| `minPrice` | integer | none | Keep products at or above this price (AUD). |
| `maxPrice` | integer | none | Keep products at or below this price (AUD). |
| `fetchReviews` | boolean | `true` | Attach reviews and review stats to each product. |
| `maxReviews` | integer | `20` | Cap on reviews captured per product (maximum 1000). `0` disables reviews. |
| `maxItems` | integer | `20` | Total products to return. `0` = unlimited. |
| `maxPages` | integer | `0` | Safety cap on result pages per search term. `0` = no cap; a run still stops on its own once the storefront's result total is reached or a page repeats. |
| `storePostcodes` | array | none | Up to 5 Australian postcodes. Adds `storeAvailability` for the 5 stores nearest each postcode (plus any farther store Kmart lists for a size). Empty = off, nothing extra billed. |
| `storeNames` | array | none | Up to 10 Kmart store names (for example `["Coomera", "Oxenford", "Helensvale"]`) or store ids. Picks the exact stores to monitor: the actor finds the postcodes itself and `storeAvailability` lists only these stores. Use either this or `storePostcodes`, not both. Empty = off. |
| `includeClickAndCollect` | boolean | `true` | With Store postcodes or Store names: also check Click & Collect and exact units at Kmart's 3 nearest Click & Collect stores (one extra lookup per variant per postcode). Off = in-store stock level only. |
| `trackStates` | array | none | States to track, e.g. `["QLD"]`. Adds `inStockInSelectedStates`; in Incremental mode only these states' `outOfStockStates` flags count as a change. |
| `verifyOnlineDelivery` | boolean | `false` | Check online delivery live for the tracked states with Kmart's own delivery check (one lookup per size and state). `inStockInSelectedStates` then follows the live answer. |
| `deliveryPostcode` | string | none | With the live delivery check in Search or URL mode: replace the capital-city postcode for exactly one Tracked state, for example `"4209"` with `["QLD"]`. No store or Click & Collect lookups are enabled. Keep the existing State key and history; differing answers return in `deliveryChanges`. |
| `returnDeliveryAnswers` | boolean | `false` | One-off, needs Incremental mode and the live delivery check: returns every scanned product as an `UPDATED` row (short with Compact updates on) with its verified delivery answer per size and state (`deliveryChanges`), whatever the saved history says. Turn it off after one run. |
| `resumeFromRunId` | string | none | Continue one specific interrupted previous run or dataset: products already collected there are skipped. |
| `incrementalMode` | boolean | `false` | Daily or recurring monitoring of the same search, specials collection, or URL set. See "Resume and recurring updates" above. |
| `stateKey` | string | none | Optional name for a monitoring campaign. Auto-derived from your search and filter settings when left empty. |
| `baselineDatasetId` | string | none | Incremental mode only. Pick the dataset of an earlier run of this Actor to use as the starting point, so the first Incremental run returns only changes. Not combinable with Resume. |
| `emitUnchanged` | boolean | `false` | Incremental mode only. Also return products unchanged since the last run, marked `UNCHANGED`. |
| `emitExpired` | boolean | `false` | Incremental mode only. Also return products from a previous run no longer found, marked `EXPIRED`, once a run has fully scanned the tracked search or URLs. |
| `changeScope` | string | `all` | Incremental mode only. `priceAndStock` makes only price changes (including each variant's price) and stock changes (national and per variant, limited to `trackStates` when set) return `UPDATED`; changes to descriptions, images, badges, shipping or other details never do. `priceAndLocalStock` (needs `storePostcodes`) makes only price changes and in-stock or Click & Collect changes at your selected stores return `UPDATED`; Kmart's state and national flags are not compared. `sellingPriceAndStock` works like `priceAndStock`, but a price change counts only when the selling price (`currentPrice`, for the product or a variant) moves: Kmart's scheduled or expired promotion entries, was prices and savings never return a row on their own. Changing `changeScope`, `trackStates` or `fetchReviews` on a search with no `stateKey` continues from that search's saved baseline, so unchanged products are not returned or billed again; set a new `stateKey` if you want a fresh start. With `storePostcodes` set, a store availability change returns `UPDATED` in every scope; unit counts and stock bands alone never do. |
| `compactUpdates` | boolean | `false` | Incremental mode only. `UPDATED` and `EXPIRED` rows are short: ids (including the `apn` barcode), url, name, current price and stock, plus `priceChanges` and `variantChanges` with the old and new value of each moved field (and `otherChanges` for every other moved field with `changeScope` `all`), and `storeChanges` (old and new availability per store and variant) when Store postcodes is set. `NEW` rows always carry the complete record. Reviews are not included in compact rows and are not billed for them. |
| `expireAfterMissedScans` | integer | `1` | Incremental mode only, with `emitExpired`. A product is marked `EXPIRED` only after it has been missing from this many full scans in a row, so a product that briefly drops out of a listing is not reported as gone. Availability itself is reported by the stock fields. |
| `ignoreFieldsForChanges` | array | `[]` | Incremental mode only. Extra field names to exclude from `UPDATED` change detection, on top of the built-in exclusions (reviews, review stats, average rating, group ids). A dotted name such as `variations.image` ignores that key inside every variant while variant prices and stock stay tracked. |
| `proxy` | object | `{ "useApifyProxy": true }` | Connection configuration. |
| `mcpConnectors` | array | none | Optional MCP connectors to export results into. |
| `notionParentPageUrl` | string | none | Notion parent page for the Notion connector. |
| `maxNotifyListings` | integer | `50` | Cap on items exported per connector. |

**Every product in Kmart's current promotional catalogues (Weekly catalogues):**

```json
{
  "mode": "search",
  "specialsCategory": "weekly-catalogues",
  "fetchReviews": false,
  "maxItems": 0,
  "incrementalMode": true
}
```

**Basket input:**

```json
{
  "mode": "basket",
  "storeNames": ["Coomera", "Oxenford", "Helensvale"],
  "trackStates": ["QLD"],
  "basketItems": [
    {"url": "https://www.kmart.com.au/product/soft-shorts-s175824/", "colour": "Black", "size": "10", "quantity": 2},
    {"url": "https://www.kmart.com.au/product/madison-bath-towel-ocean-42442370/", "quantity": 1}
  ]
}
```

### Output Example

> Sample shape: values are illustrative placeholders, not from a live listing.

```json
{
  "kind": "product",
  "id": "42442370",
  "name": "Sample Bath Towel",
  "title": "Sample Brand Sample Bath Towel",
  "url": "https://www.kmart.com.au/product/sample-bath-towel-42442370/",
  "brand": "Sample Brand",
  "apn": 9300000000000,
  "description": "Sample lead sentence about the product.<br /><br /><strong>Product Details</strong><ul><li><strong>Dimensions/Size:</strong> 000cm (L) x 00cm (W)</li><li><strong>Material:</strong> Cotton</li></ul><strong>Features</strong><ul><li>Sample feature</li></ul><strong>Care Instructions</strong><ul><li>Warm machine wash with similar colours</li></ul>",
  "descriptionText": "Sample lead sentence about the product.\nProduct Details:\n- Dimensions/Size: 000cm (L) x 00cm (W)\n- Material: Cotton\nFeatures:\n- Sample feature\nCare Instructions:\n- Warm machine wash with similar colours",
  "descriptionSummary": "Sample lead sentence about the product.",
  "features": ["Sample feature"],
  "specifications": { "Dimensions/Size": "000cm (L) x 00cm (W)", "Material": "Cotton" },
  "careInstructions": ["Warm machine wash with similar colours"],
  "additionalInfo": null,
  "warnings": null,
  "manuals": null,
  "detailSections": [
    { "heading": "Product Details", "items": ["Dimensions/Size: 000cm (L) x 00cm (W)", "Material: Cotton"] },
    { "heading": "Features", "items": ["Sample feature"] },
    { "heading": "Care Instructions", "items": ["Warm machine wash with similar colours"] }
  ],
  "price": 8.0,
  "currentPrice": 8.0,
  "listPrice": 8.0,
  "promoPrice": 12.0,
  "wasPrice": 12.0,
  "savingsAmount": 4.0,
  "savingsPercent": 33,
  "isOnSpecial": true,
  "promoLabel": "Clearance",
  "currency": "AUD",
  "onSale": false,
  "clearance": true,
  "freeShipping": false,
  "averageRating": 4.6,
  "reviewCount": 316,
  "colour": "Blue",
  "size": "One Size",
  "seller": "kmart",
  "isMarketplace": false,
  "merchDepartment": "Home",
  "inStockNationally": true,
  "images": ["https://assets.kmart.com.au/transform/00000000-0000-0000-0000-000000000000/42442370-1"],
  "variations": [
    { "colour": "Blue", "size": "One Size", "price": 12.0, "apn": 9300000000000, "inStock": true, "outOfStockStates": null },
    { "colour": "Grey", "size": "One Size", "price": 12.0, "apn": 9300000000001, "inStock": false, "outOfStockStates": ["ACT", "NSW", "NT", "QLD", "SA", "TAS", "VIC", "WA"] }
  ],
  "reviewStats": {
    "totalReviews": 316,
    "averageScore": 4.58,
    "starDistribution": { "5": 222, "4": 64, "3": 24, "2": 4, "1": 2 },
    "subRatings": { "Value": 5.0, "Quality": 4.0 }
  },
  "reviews": [
    {
      "rating": 5,
      "title": "Sample title",
      "content": "Sample review text.",
      "author": "Sample R.",
      "createdAt": "2026-01-01T00:00:00.000Z",
      "verifiedBuyer": true,
      "votesUp": 6,
      "votesDown": 0,
      "subRatings": { "Value": 5, "Quality": 5 }
    }
  ]
}
```

#### Store availability near your postcode (optional)

Set **Store postcodes** (for example `["4209"]`) and every product gets `storeAvailability`: one entry per nearby Kmart store and per colour/size variant, read from the same stock service Kmart's product page uses for its In-store and Click & Collect tiles. Every variant is reported for the same fixed set: the postcode's 5 nearest Kmart stores (for 4209: Coomera, Oxenford, Helensvale, Southport, Broadbeach). A variant can also list a few farther stores, because Kmart's in-store list names the 5 nearest stores that hold a stock record for that particular size (for a size missing from the nearest store, it reaches out to Robina or Loganholme). Add another postcode to cover another area (for example `4000` for central Brisbane next to `4209` for the northern Gold Coast).

To monitor specific stores instead, set **Store names** (for example `["Coomera", "Oxenford", "Helensvale"]`). Names match the Kmart store finder (a leading Kmart or Westfield is optional, a trailing state such as `Burwood NSW` is accepted, and a store id always works; if two stores share a name the run stops and lists their ids). The actor works out the fewest postcodes that cover your stores and `storeAvailability` then lists only those stores, so rows are smaller and a stock change at any other store never returns a row. Exact Click & Collect units come from Kmart's 3 nearest Click & Collect stores, so a store outside that group for its area reports its stock level only. A name that matches no store, matches two, or is outside Australia stops the run before any product is read, with a message naming it.

> Sample shape: values are illustrative placeholders, not from a live listing.

| Field | Example |
| --- | --- |
| `storeId` | `"1000"` |
| `storeName` | `"Sample Store"` |
| `address` | `"1 Sample Road"` |
| `suburb` | `"Sampleton"` |
| `state` | `"QLD"` |
| `postcode` | `"4000"` |
| `phone` | `"+61 7 0000 0000"` |
| `distanceKm` | `1.6` |
| `nearPostcode` | `"4209"` |
| `clickAndCollectEnabled` | `true` |
| `variationId` | `"42442370"` |
| `colour` / `size` | `"Blue"` / `"One Size"` |
| `stockLevel` | `"High"` |
| `inStock` | `true` |
| `stockSource` | `"inStoreList"` |
| `unitsAvailable` | `12` |
| `clickAndCollectAvailable` | `true` |
| `clickAndCollectUnits` | `12` |

`stockLevel` is Kmart's own band (`High`, `Medium` or `Low`). Measured against the exact counts: `Low` always came with 0 sellable units, `Medium` with a small count (1 to 5 seen) and `High` with a larger one (6 or more seen), so `inStock` is `true` for `High` and `Medium`. `stockSource` says where `inStock` came from: `inStoreList` (Kmart's band for that store), `clickAndCollect` (the exact units, for a store the in-store list skipped), `notListed` (the store is nearer than stores the in-store list did name but holds no stock record for that size: not in stock; in testing every such store also answered 0 units on Click & Collect), or `null` with `inStock: null` (a store farther than every listed one: unknown). `unitsAvailable`, `clickAndCollectAvailable` and `clickAndCollectUnits` are filled for Kmart's 3 nearest Click & Collect stores when **Include Click & Collect and exact units** is on, and `null` for the other stores. Each row also gets `inStockAtSelectedStores` (any variant in stock at any selected store) and `storesInStock` (the names of those stores). A size for which Kmart holds no stock record at any store near the postcode is still reported for the 5 nearest stores, each `inStock: false` with `stockSource: "notListed"`, so a later restock there comes back as a change. If the store lookup cannot be read for a product, `storeAvailability` is `null`, and a size whose own lookup could not be read is left out of the list. Rows of products with many sizes get long, since every size is listed for every store.

**Tracked states** (`trackStates`, for example `["QLD"]`) needs no extra lookups: it adds `inStockInSelectedStates` to each variant and to the product (`true` when none of the chosen states is in `outOfStockStates`), and in Incremental mode only those states count as a stock change. That flag comes from Kmart's product listings and can lag real online availability (see the FAQ on `outOfStockStates`).

**Check online delivery live** (`verifyOnlineDelivery`, needs Tracked states) asks Kmart's own delivery check for every colour/size and every tracked state, at the state's capital-city postcode unless **Delivery postcode** (`deliveryPostcode`) overrides it. To check QLD at 4209, set `"trackStates": ["QLD"]`, `"verifyOnlineDelivery": true` and `"deliveryPostcode": "4209"`. An override requires exactly one tracked state and replaces its destination; it adds no requests or store lookups. Keep the same `stateKey`, `changeScope` and price settings: the first check at the new postcode compares against the saved delivery answers and returns differences in `deliveryChanges`; unchanged products remain suppressed with `"emitUnchanged": false`. Keep `"returnDeliveryAnswers": false` for normal daily monitoring. Each variant gets `onlineDelivery` (for example `{"QLD": false}`; `null` for a check that could not be read), and `inStockInSelectedStates` then follows that answer (read it, and `onlineDelivery`, rather than `outOfStockStates`, which is the listing flag and can still move on its own and return a row): `true` only when every tracked state delivers, `false` when any does not, `null` when unknown. In Incremental mode a delivery answer that flips between two runs returns an `UPDATED` row (`changedFields` names `onlineDelivery`; compact rows list it in `deliveryChanges`); turning the check on for an existing state key does not re-emit tracked products, except one-time corrections: the first verified run returns an `UPDATED` row for a product when a size's verified answer differs from the availability that state key had exported before (its `deliveryChanges` entry carries `reconciled: true`, with the previous exported availability as `old`, listed only for states whose verified answer differs from it; a size whose very first verified check could not be read keeps its pending correction until a later run can read it); a check that could not be read is never reported as a change. For a task whose saved state already holds delivery answers you never received, turn on **Return verified delivery answers once** (`returnDeliveryAnswers`, needs Incremental mode and this check) for one run: every scanned product comes back as an `UPDATED` row (short with Compact updates on, the full row otherwise) whose `deliveryChanges` lists its verified answer per size and state (`reconciled: true`, `old: null`), whatever the saved history says; turn it off afterwards, as it returns every scanned product each time it is on. It is one lookup per size and state, so a listing of many sizes takes noticeably longer.

**Reading the delivery answers (for importers).** Unread checks are retried once in the same run; a check that still cannot be read is `null` (unknown), never `false`. When a size's check could not be read the first time it was made, or the size is new on a product already checked, the first run that reads it returns the product once as `UPDATED` with that answer in `deliveryChanges` (`old: null`, `reconciled: true`), because that answer was never returned before; the same answer is not returned again. The examples use QLD; the same holds for every tracked state.

| What the row shows | What it means | What to store |
|---|---|---|
| A full row: `variations[].onlineDelivery.QLD` is `true` or `false` | Confirmed this run for that size; with one tracked state that size's `inStockInSelectedStates` is the same value | That answer |
| A full row: `variations[].onlineDelivery.QLD` is `null` (the size is also listed in `deliveryUnread`) | Not confirmed this run: the check could not be read; never shown as `false` | Keep your previous value |
| A compact `UPDATED` row: a `deliveryChanges[]` entry (`old`, `new`) | Confirmed this run; `reconciled: true` marks a one-time correction or a first known answer (`old` may then be `null`) | `new` |
| A compact `UPDATED` row: a size and state listed in `deliveryUnread` | Not confirmed this run | Keep your previous value |
| A compact `UPDATED` row: a size and state in neither list | Confirmed this run and unchanged (in a "Return verified delivery answers once" run every confirmed answer is listed in `deliveryChanges`) | Keep your previous value |
| `deliveryUnread` is `null` | Every check of that row answered | |
| No row for a product (Incremental mode) | Nothing you compare changed; in a "Return verified delivery answers once" run, a product you expected but did not get could not be confirmed at all (every check failed) and is listed in the run summary's `deliveryUnreadProducts` | Keep your previous values |
| Product-level `inStockInSelectedStates` | `true` if any size is `true`, else `false` if any size is `false`, `null` only when every size is unread; never proof that every size was confirmed | Do not use it per size |
| `outOfStockStates` | Kmart's listing flag | Never the delivery answer |

`deliveryUnread` is on every row returned while **Check online delivery live** is on: a list of `{variationId, colour, size, state}` for the checks that could not be read this run, or `null`. It is never compared and costs nothing. **Return verified delivery answers once** returns a row only for an `UNCHANGED` or `UPDATED` product with at least one answered check (a `NEW` or `REAPPEARED` product is returned anyway, with its answers); a product whose every check could not be read is not returned, because a row without the requested answer would be billed for nothing, and is listed instead in `deliveryUnreadProducts` (first 100 ids, total in `deliveryUnreadProductsCount`). In the run summary `unchangedSuppressed` counts distinct products and `failedDeliveryChecks` counts distinct size and state checks of the run, split into `failedDeliveryChecksReturned` (on rows returned), `failedDeliveryChecksSuppressed` (on products suppressed as unchanged) and `failedDeliveryChecksDropped` (checked, but the product was not returned).

When `incrementalMode` is on, every returned record also carries `changeType` (`NEW`, `UPDATED`, `UNCHANGED`, `REAPPEARED` or `EXPIRED`), `changedFields` (non-empty only for `UPDATED`), `firstSeenAt` and `lastSeenAt`. Change detection compares the product itself (price, was/now pricing and specials, stock including the per-variant `inStock`/`outOfStockStates` on each colour/size, brand, colour, size, seller, images and the description); `reviews`, `reviewStats`, `averageRating`, `reviewCount` and `groupIds` are deliberately excluded, because a new review or a fresh vote count between two runs does not mean the product changed. Store availability is compared separately: only `inStock` and `clickAndCollectAvailable` of a store and variant seen in both runs count (`changedFields` then names `storeAvailability`); the 5 nearest stores are reported for every size, so a size coming back in stock there (from `notListed` or 0 units to in stock) is a change; a farther store that only some runs list, a size or postcode whose lookup could not be read this run, and unit counts or stock bands never return a row on their own. Adding Store postcodes to an existing explicit `stateKey` does not re-emit tracked products; with an automatic state key, a new store selection starts its own state (everything `NEW` once).

#### Basket check: exact size and quantity at your stores

Set `mode` to `basket`, pick your stores with **Store names** (or **Store postcodes**) and list the basket lines. Each line is checked for its own size and colour only, so a line costs one exact-units lookup per store area instead of one per size of the product, and a whole basket is looked up in parallel.

See the basket input example under **Input Parameters**.

Each checkable line returns one row (`kind: "basketLine"`) with `basketLine`, `requestedQuantity`, the variant's `variationId`, `apn`, `colour`, `size`, its payable `currentPrice` (plus `price`, `wasPrice` and the saving fields), `inStockNationally`, `inStockInSelectedStates`, and `storeAvailability` with, per selected store, `stockLevel`, `inStock`, `unitsAvailable`, `clickAndCollectUnits` and `enoughStock` (`true` when the store has at least the requested quantity, `null` when Kmart gave no exact count for that store). `enoughStockAtSelectedStores` and `storesWithEnoughStock` sum it up. `deliveryAvailable` is Kmart's live home-delivery answer for the store area's postcode (`deliveryPostcode`), asked in the same lookup as the store stock, so it needs no additional lookup; it is `null` without stores or with **Include Click & Collect and exact units** off. A line whose product is not listed, or whose colour and size do not pick exactly one variant, returns no row; the **BASKET_SUMMARY** record in the run's key-value store lists every line with its status (`checked`, `needsVariant`, `notFound`, `lookupFailed` or `notChecked`) and the reason. Exact units need **Include Click & Collect and exact units** on (the default). Without stores, a line still returns its price and national and state stock. Incremental mode and Resume do not apply to a basket check: every checkable line is returned every time. **Max products** still caps the rows: set it to at least the number of basket lines (or `0` for no cap), otherwise the lines past it are reported as `notChecked`.

Each basket line can name the product by `productId` (for example `"43572342"` or `"S175824"`) instead of `url`. To get the rows back in the same API request, which is the fastest way to use a basket check at checkout, call the Actor through Apify's synchronous endpoint `POST https://api.apify.com/v2/acts/<actor id>/run-sync-get-dataset-items` with the input above as the request body; it returns the dataset rows when the run finishes.

The stores picked by **Store names** are remembered on your account for a week (key-value store `kmart-lite-store-selection`), so repeated runs with the same names skip the store lookup and start checking straight away.

#### Output views

The dataset has six views in the Console: **Products Overview** (price, discount, rating, stock and images), **Reviews** (one row per product with its `reviews` list and rating summary in single columns), **Variants & stock** (one row per product with its colour/size `variations` list, each with its own stock status, in a single column), **Store availability** (`inStockAtSelectedStores`, `storesInStock` and the `storeAvailability` list, filled when Store postcodes is set), **Basket check** (one row per basket line with the requested quantity and the stores that have it) and **Changes (incremental)** (`changeType`, `changedFields` and `storeChanges`, populated when Incremental mode is on).

### Plan Requirement

The default proxy setting works out of the box on standard Apify datacenter proxies; residential proxies are not required. The actor reads Kmart's product data feeds rather than its web pages, and those feeds load through a datacenter connection. The actor manages its own connection tiers and moves to a backup connection when one is persistently refused, so there is nothing to tune under Connection. A paid Apify plan (https://apify.com/pricing) or your own proxy URLs is needed, because Apify free plans do not include proxy access.

What you may see in the run log:

- If the selected connection is unavailable (Apify free plans do not include residential proxies), the run logs "The selected connection is unavailable to this run" and continues on a backup connection; some pages may still be unavailable. When that backup serves the run, the log says "Served over the backup connection (the default connection was unavailable)."
- If the proxy refuses the account, the run ends FAILED with: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required." Check your own proxy URLs' credentials if you entered any.
- If residential proxies are unavailable and the backup connection could not load the requested pages, the run ends with "No results: residential proxies are unavailable on this run (Apify free plans do not include them)".
- If requests fail for another reason, the run ends with "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later."

### FAQ

#### How much does it cost?

You pay one product event per returned dataset row and one run-start event per run, plus Apify platform usage for compute, proxies, storage and data transfer. The Pricing tab shows the current rates for your plan. This private Lite version has no review, store-availability or delivery enrichment event fees. Optional reviews, store lookups and delivery checks still consume platform resources. With the live delivery check, a size whose answer is read for the first time after earlier unreadable checks, or a size newly added to a product already checked, returns the product once as an `UPDATED` row, a returned row like any other. Use **Max products**, **Max pages**, **Max reviews per product** and the platform run limits to bound work.

#### Is it legal to scrape Kmart Australia?

This actor collects only publicly available product and review data. You are responsible for how you use it: follow Kmart's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product names, prices and specifications are generally facts, but photos and customer review text may be subject to third-party rights.

#### Can I get only new or changed products on a schedule?

Yes. Schedule the actor from the **Schedules** tab and turn on **Incremental mode**. Each run then returns only new and updated products by default, and unchanged ones are suppressed.

#### How do I apply `UPDATED` rows?

`changedFields` names the fields that changed. A full `UPDATED` row is the whole current record: replace your copy of that product (matched on `id`). A compact row (`compactUpdates`) carries the details in its sections: `priceChanges` (product prices), `variantChanges` (per colour/size, matched on `variationId`: `ADDED`, `REMOVED` or `CHANGED` with the old and new value of each moved field), `deliveryChanges` (per size and tracked state), `storeChanges` (per store and size) and, with `changeScope` `all`, `otherChanges` (the old and new value of every other moved field, such as the description or name; with `all`, `variantChanges` also lists moved images and labels). Apply each `new` value and keep everything else. Every compact `UPDATED` row has at least one of these sections filled, and the same variants listed in another order, or a stock move in a state you do not track, never return a row. A `deliveryChanges` entry with `reconciled: true` is a one-time correction of the delivery availability exported before the live check was on (`old`) to the verified answer (`new`); apply it like any other change.

#### Which price field is the current selling price?

Use `currentPrice`, on each product and on each variant: it is the payable price. It is the lowest list or promotional price in Kmart's price table whose dates include today (so an expired promotion or a superseded list price never counts) and that a seller offer on the listing (Kmart, Target or a marketplace seller) currently charges: an offer's discount price while its discount dates are running, otherwise its regular price. When no table price matches a current offer, `currentPrice` is the listing's `price`, the offer the site shows; this also applies to items Kmart sells itself whose table price no offer charges. Kmart's price table can hold placeholder amounts far below the real price (on listings only Target or marketplace sellers offer) as well as ordinary-looking prices that no seller currently charges. A listing without seller offers uses the table alone, and equals `price` when the table has no active entry. When Kmart's own offer sits next to a cheaper marketplace offer, `currentPrice` stays Kmart's price while `price` shows the cheaper offer. `listPrice` and `promoPrice` are Kmart's price-table entries as published, so they can show such an amount: do not read them as the selling price. On an `UPDATED` row, `previousPrice` holds the selling price before the run (empty when the selling price did not move), and compact rows show the same old value per variant in `variantChanges`. With `changeScope` `all`, `priceAndStock` or `priceAndLocalStock`, `currentPrice` and `previousPrice` never decide whether a row is `UPDATED` by themselves, so adding them does not reset a saved baseline; with `sellingPriceAndStock`, a move of `currentPrice` does.

#### How do I recover prices or barcodes for products I already imported?

Products imported earlier can hold a `currentPrice` taken from a table price that no seller charged (a placeholder amount, or an ordinary-looking price no offer carried), and compact rows from earlier runs carried no barcode. To fill your copy, start one separate run (not your scheduled Task) with `"mode": "url"`, the product numbers as bare ids in `urls` (for example `["43050024", "43120147"]`), `"incrementalMode": false`, `"fetchReviews": false` and `"maxItems": 0`. It returns each product's full current record, with `currentPrice` and `apn` on the product and on every variant, and it neither reads nor changes the saved history of your Incremental Task. Each returned product is billed as a normal product row. Your scheduled Task then carries on as before: with `changeScope` `all` or `priceAndStock`, its next normal run stores the corrected `currentPrice` silently (no row is returned for it), and with `sellingPriceAndStock` it returns each corrected product once as `UPDATED` (`changedFields` names `currentPrice`; a compact row's `priceChanges.currentPrice` holds the old and the new payable price).

#### How do I check what a run did?

Every run writes a `RUN_SUMMARY` record to its key-value store and prints it as one `Run summary:` log line. What each field means:

- `scanComplete`: `true` only when every link and search term was walked to its own natural end in this run: not capped by Max products, Max pages or the run's maximum charge, not a resumed or restarted run, not stopped before the time limit, and no listing page failed. It says nothing about the delivery checks or store lookups (see the fields below). Only a complete scan can mark products `EXPIRED`.
- `productsScanned`: products handled this run, returned or suppressed as unchanged. `rowsReturned`: rows in the run's dataset, including rows saved before a restart.
- `restartedAfterMigration`: `true` when the platform moved or restarted the run and it carried on from where it stopped. The row counters (`rowsReturned`, `newRows`, `updatedRows`, `unchangedReturned`, `expiredRows`), `productsScanned` and `unchangedSuppressed` then cover the whole run, before and after the restart. The request and delivery-check failure counters cover only the work after it.
- `walkReachedEnd`: `true` when every link and search term was walked to its natural end, even if the run was restarted on the way. It is `false` for a capped, stopped or short walk, or when a listing page was skipped, or when the earlier part of a restarted run cannot be vouched for. Use it to tell a restarted run that missed nothing from one that did. `scanComplete` stays `false` after any restart, because the products met before it are not known, so `EXPIRED` is never decided from it.
- `listingPagesSkipped`: listing pages that could not be read, or that repeated products already returned, and were stepped over so the rest of the listing was still collected (up to two in a row). Any skipped page makes `scanComplete` false; run again to collect the products on those pages.
- `failedRequests`: requests of any kind (listing pages, reviews, store lookups, delivery checks) that got no usable answer after their retries, summed over every connection the run used. A delivery check counted here is also counted in `failedDeliveryChecks`, so the two overlap.
- `failedDeliveryChecks`: distinct size and state delivery checks left unread after their retry (shown as `null`). `deliveryChecksAttempted`, `deliveryChecksAnswered`, `deliveryCoverage` (answered divided by attempted), `deliveryChecksRecovered` (answered on their retry), `deliveryProductsWithUnread` (products with at least one unread size) and `deliveryComplete` (`true` only when every check answered) describe the delivery checks; all are `null` when the check is off. Below 99 % coverage the run's status message says how many checks could not be read; the run still succeeds.
- `failedStoreLookups`: store lookups that could not be read. `stoppedAtChargeLimit`: the run reached its maximum total charge. `stoppedAtTimeLimit`: the run stopped about a minute before its time limit to save its work.

Lite reports `billingModel: "pay-per-event-plus-platform-usage"` and tallies the automatic product and run-start event units in `chargedEvents`. The platform run details are the authority for final event charges, and the Usage tab records resource costs.

#### Why does the was/original price come back null for most products?

Kmart runs an everyday-low-price model rather than constant discounting, so `wasPrice`, `savingsAmount` and `savingsPercent` are populated only when an item is genuinely reduced right now. A product with no active promotion returns those fields as `null`, and `isOnSpecial` reflects its clearance status instead.

#### Why did my run fail or return nothing?

The run fails outright only when a Resume id cannot be read, or when Resume is combined with Incremental mode on a search that already has saved monitoring state. If requests keep being refused after retries, the affected search or page is skipped with a warning in the log. A run that ends with no products finishes with a status message asking you to check your search terms, URLs and filters, so look at the log for fetch warnings before assuming nothing matched. A pasted category URL that does not match a Kmart category is reported and skipped. A pasted marketplace product URL returns nothing while Include marketplace products is off, and a pasted product that none of your picked Sellers sells returns nothing either. A Sellers value other than Kmart, Target, Officeworks or Marketplace stops the run at the start. A Store postcodes value that is not a 4-digit postcode, or "Price and local store availability" without any Store postcodes, stops the run at the start with a message saying what to fix.

#### Can I leave out Officeworks products and keep Kmart and Target?

Yes. Set **Sellers** to Kmart and Target (`"sellers": ["Kmart", "Target"]`) on your existing Task and leave everything else as it is. Products that Kmart or Target sell come back as before, including the ones Officeworks also sells; only products sold by Officeworks alone (or by Officeworks and marketplace sellers) are left out, and nothing is billed for them. Each product is one row whatever its number of sellers, so a shared product is never returned or billed twice. In Incremental mode Sellers keeps the same saved list, with no `EXPIRED` rows for the ones left out (see "Resume and recurring updates"). If you also run the Officeworks actor, match Kmart `apn` to Officeworks `gtin` to spot the same product in both outputs; Kmart's `apn` is a number, so compare the two without leading zeros. Adding `?f.Seller=Kmart&f.Seller=Target` to pasted listing links does the same for those links, but it changes the links and so the automatic state key (every product `NEW` once), and it cannot filter pasted product links; Sellers covers both.

#### How do I watch stock at my local Kmart stores?

Schedule a daily run with this input (paste your product, category or search links, and your postcodes):

```json
{
  "mode": "url",
  "urls": ["https://www.kmart.com.au/product/sample-bath-towel-42442370/"],
  "storePostcodes": ["4209", "4000"],
  "includeClickAndCollect": true,
  "trackStates": ["QLD"],
  "incrementalMode": true,
  "changeScope": "priceAndLocalStock",
  "compactUpdates": true,
  "stateKey": "my-local-stores",
  "fetchReviews": false,
  "maxItems": 0
}
```

The first run returns every product in full as `NEW`. Later runs return a product only when its price (or a variant's price) changed, or when a variant went in or out of stock, or in or out of Click & Collect, at one of the 5 stores nearest each postcode; compact rows list each move in `priceChanges`, `variantChanges` and `storeChanges` (old and new). Unit counts and stock bands moving on their own never return a row, and neither does a stock change in another state. For products with many sizes, turning `includeClickAndCollect` off keeps runs faster and cheaper (in-store stock level only).

To watch named stores instead, replace `storePostcodes` with `"storeNames": ["Coomera", "Oxenford", "Helensvale"]`.

For state-level tracking only (no store lookups, no store events), drop `storePostcodes` and `includeClickAndCollect` and use `"changeScope": "sellingPriceAndStock"` with `"trackStates": ["QLD"]`. A row then comes back when the selling price moves or when a variant's Queensland flag in `outOfStockStates` appears or clears; flags for other states and the national roll-ups are ignored.

#### Does `outOfStockStates` tell me whether my local store has it?

No, and it is not a reliable online-delivery signal either. It is a per-state flag carried in Kmart's product listings, and it often lags what Kmart will actually deliver: in a sample of 140 clearance items whose list did not include `QLD`, 36 could not be delivered to a Queensland postcode (the product page showed "sold out online" or "Click and collect only"), and sizes whose list did include `QLD` were sometimes deliverable. For a dependable answer, turn on **Check online delivery live** (`verifyOnlineDelivery`) with your **Tracked states**: each size is then checked with Kmart's own delivery check, the one the product page uses. Use **Store postcodes** or **Store names** for stock on the shelves of particular stores.

#### Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push a summary of each product into Notion, Linear or Airtable.

### 🔗 Want more Kmart data?

Pair this actor with these related scrapers from the same team:

<table>
<tr><td>🛒 <a href="https://apify.com/abotapi/kmart-au-scraper"><b>Kmart Scraper</b></a><br>Scrape products and customer reviews from Kmart.com.au. Search by keyword or use...</td><td>🛒 <a href="https://apify.com/abotapi/target-au-scraper"><b>Target AU Scraper</b></a><br>Scrape products and customer reviews from Target.com.au. Search by keyword or use...</td></tr>
<tr><td>🛒 <a href="https://apify.com/abotapi/bigw-marketplace-scraper"><b>BIG W Marketplace Scraper</b></a><br>Scrape BIG W Marketplace seller listings from bigw.com.au: name, brand, price, was-price...</td><td>🛒 <a href="https://apify.com/abotapi/zalando-scraper"><b>Zalando Scraper</b></a><br>Scrape Zalando products: name, brand, current and original price, discount, sizes...</td></tr>
<tr><td>🛒 <a href="https://apify.com/abotapi/costco-au-scraper"><b>Costco AU Scraper</b></a><br>Scrape Costco.com.au products by keyword or product, search and category URLs. Extract...</td><td>🛒 <a href="https://apify.com/abotapi/muji-scraper"><b>MUJI Scraper</b></a><br>Scrape MUJI products from the United States, Canada and Australia storefronts. Search by...</td></tr>
</table>

👉 [Browse all abotapi scrapers](https://apify.com/abotapi)

### 💬 Support

- 🐞 **Found a bug or a missing field?** Open a ticket on the [Issues tab](https://apify.com/abotapi/kmart-au-scraper-lite/issues/open). We usually reply within hours.
- 🛠️ **Need another site, extra fields or a private build?** Email <contact@abotapi.com>.
- ⭐ **Enjoying it?** A quick review on the actor page helps other users find it.

# Actor input Schema

## `mode` (type: `string`):

search = provide search terms. url = paste product, category, or search URLs and walk them. The sort and filter fields further down (sort, brand, colour, category, marketplace, price range) apply in both modes. basket = check the exact size/colour and quantity of each basket line at your selected stores (see Basket check below).

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

One or more keywords to search, e.g. towel, air fryer, kids toys. Search mode only.

## `specialsCategory` (type: `string`):

Optionally scrape one of Kmart's promotional collections instead of (or alongside) your search terms: Clearance, the current Catalogue, or Online Exclusives. Leave as None to search normally. Was/original price and discount fields are captured on every product when the item is genuinely reduced. Search mode only: in URL mode, paste the collection's own URL instead. Weekly catalogues reads every product in Kmart's current promotional catalogues (the ones on the Catalogue page, with their offer dates); Catalogue is Kmart's small fixed catalogue collection.

## `urls` (type: `array`):

Paste product, category, or search URLs from kmart.com.au. Multi-URL supported. The sort and filter fields below still apply: to a pasted category, search, or specials collection URL exactly as in Search mode, and the price range plus the marketplace toggle even to a single pasted product URL, because those are checked on each product after it is fetched. Only sort and the brand/colour/category filters have no effect on a single pasted product URL, since it is looked up directly by id. Note that 'Include marketplace products' is off by default, so a pasted product URL for a third-party marketplace item returns nothing until you tick it. Supported shapes: department pages (/toys/, with ?page=N honoured), specials (/catalogue/, /clearance/, /category/online-exclusives/), brand pages (/brand/target/), search, nested category and product pages. Facets ticked on the site and carried in the pasted link (for example ?f.Shops=Kmart\&f.Shops=Target) are applied, so you get the same products the page shows for that link. An unsupported or unresolvable URL is skipped with a warning in the log. A bare Kmart product id (for example 43572342, or a clothing style id such as S175824) is accepted in place of a product URL.

## `basketItems` (type: `array`):

Basket check mode only. One entry per basket line: {"url": "\<kmart.com.au product URL>" (or "productId": "43572342"), "colour": "Black", "size": "10", "quantity": 2}. Use "variantId" (the variant id or APN) instead of colour and size if you have it. A product sold in one size and colour needs only the url. Up to 50 lines per run, and Max products caps how many are checked (set it to at least your number of lines, or 0); one row per line that could be checked, and the status of every line in the BASKET_SUMMARY record.

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

Order of results within each search or specials collection. Applies in Search mode and to a pasted category, search, or specials URL in URL mode. No effect on a single pasted product URL.

## `brand` (type: `string`):

Filter to one brand (exact facet value, e.g. Anko). Applies in Search mode and to a pasted category, search, or specials URL in URL mode. No effect on a single pasted product URL.

## `colour` (type: `string`):

Filter to one colour (exact facet value, e.g. Blue). Applies in Search mode and to a pasted category, search, or specials URL in URL mode. No effect on a single pasted product URL.

## `category` (type: `string`):

Filter to one category (exact facet value, e.g. Bath Towel). Applies in Search mode and to a pasted category, search, or specials URL in URL mode. No effect on a single pasted product URL.

## `includeMarketplace` (type: `boolean`):

Also keep products sold by third-party marketplace sellers. Listings carry thousands of these extra items, so they are excluded by default: only products from the Kmart, Target and Officeworks ranges are returned. Tick to include marketplace sellers too. This applies in EVERY mode: in Search mode, on a pasted category, search, or specials URL, and also on a single pasted product URL, because each product is re-checked after it is fetched. So while this is left off, pasting the URL of a third-party marketplace product returns no result at all; tick it to scrape marketplace product URLs.

## `sellers` (type: `array`):

Optional. Only return products sold by these sellers, e.g. Kmart and Target to leave out the Officeworks range. Leave empty to keep the usual choice (Kmart, Target and Officeworks, plus marketplace sellers when Include marketplace products is ticked). When set, this list replaces Include marketplace products: pick Marketplace here to include marketplace sellers. A product sold by several sellers (for example by Kmart and by Officeworks) is one row, returned and billed once, and is kept when ANY of its sellers is picked: only a product none of your picked sellers sells is left out, before anything is looked up or billed for it. Applies in Search mode, to specials, to pasted category, search and specials URLs, and to a single pasted product URL (checked after it is fetched). A pasted listing URL that already carries its own seller filter (f.Seller=...) keeps it. No effect in Basket check. In Incremental mode this does not start a new saved list: products it leaves out are kept aside, with no EXPIRED row and no charge, and are compared as usual if you choose their sellers again.

## `minPrice` (type: `integer`):

Only keep products at or above this price. Applies in Search mode and to every pasted URL in URL mode, including a single pasted product URL.

## `maxPrice` (type: `integer`):

Only keep products at or below this price. Applies in Search mode and to every pasted URL in URL mode, including a single pasted product URL.

## `fetchReviews` (type: `boolean`):

Attach product reviews and review stats to each product.

## `maxReviews` (type: `integer`):

Cap on reviews captured per product. 0 disables reviews.

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

Total products to return across all searches or URLs. 0 = unlimited.

## `maxPages` (type: `integer`):

Safety cap on result pages per search term. Set 0 to include all available pages, subject to Max products.

## `storePostcodes` (type: `array`):

Australian 4-digit postcodes, e.g. 4209. Up to 5. When set, store lookups consume additional platform usage; there is no enrichment event fee. Leave empty to skip store availability (no store lookups).

## `storeNames` (type: `array`):

Optional. Pick the exact Kmart stores to monitor, e.g. Coomera, Oxenford, Helensvale (or a store id). Up to 10. Instead of postcodes, the actor finds each store's area itself and reports only these stores: store name, address, stock level and whether it is in stock, plus Click & Collect availability with exact units where Kmart reports them for the store (its 3 nearest Click & Collect stores). In incremental mode only these stores can return an UPDATED row. Use either Store names or Store postcodes, not both. Store lookups consume additional platform usage; there is no enrichment event fee.

## `includeClickAndCollect` (type: `boolean`):

Only used with Store postcodes. On: also checks Click & Collect availability and the exact number of units at Kmart's 3 nearest Click & Collect stores, one extra lookup per variant per postcode (slower on products with many sizes). Consumes additional platform usage; no enrichment event fee. Off: in-store stock level for the 5 nearest stores only.

## `trackStates` (type: `array`):

Optional. Pick the states you care about, e.g. QLD. Adds inStockInSelectedStates to each product and variant (true when Kmart does not flag the item out of stock in any selected state). In incremental mode, only these states' flags in outOfStockStates count as a change, and the national roll-ups (inStock per variant, inStockNationally) are not compared, so a stock change in another state never returns an UPDATED row. Kmart's state flags describe online delivery stock for the whole state, not a particular store: use Store postcodes for store stock.

## `verifyOnlineDelivery` (type: `boolean`):

Optional, off by default. Kmart's per-state flag in its product listings does not always match whether Kmart will deliver right now (a product can show "sold out online" or "Click and collect only" while the flag still lists the state as available). Turn this on to ask Kmart's own delivery check, the one the product page uses, for every colour/size and every Tracked state; inStockInSelectedStates then follows that answer and each variant gets onlineDelivery per state. Needs at least one Tracked state. One extra lookup per size and state, so runs take longer; these lookups consume additional platform usage, with no enrichment event fee. In Incremental mode a delivery change returns an UPDATED row.

## `deliveryPostcode` (type: `string`):

Optional. With Check online delivery live in Search or URL mode, replaces the capital-city postcode for exactly one Tracked state. For QLD home delivery to 4209, enter "4209" and select only QLD. Blank keeps the existing capital-city checks. Uses the same one lookup per variant and state; does not enable store or Click & Collect lookups. Keep the same State key: changed answers are returned through deliveryChanges without restarting price history.

## `returnDeliveryAnswers` (type: `boolean`):

One-off, off by default. Every scanned product is returned as an UPDATED row (short when Compact updates is on, the full row otherwise) listing its verified delivery answer per size and state (deliveryChanges, reconciled: true), whatever the saved history says. Use it once on a task whose saved state already holds delivery answers you never received, then turn it off. Needs Incremental mode and "Check online delivery live". Charged like any returned row plus the delivery check units.

## `proxy` (type: `object`):

Apify Proxy is used by default and works on every plan. Leave it enabled for reliable results.

## `resumeFromRunId` (type: `string`):

Optional. ID of a previous run of this actor (or a dataset ID). Products already in that dataset are skipped, so this run returns only NEW products (a delta). Combine both runs' datasets for the full set. Max products then counts only the new products. For recurring daily monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns all matching products as NEW. Later runs compare every product against the last run (price, was/now pricing and promos, stock including each colour/size variant, brand, colour, size, seller, images, and Kmart's own product description) and return only NEW, UPDATED, and REAPPEARED products, with an UPDATED row's changedFields naming exactly what moved. Reviews, review stats, the average rating, and Kmart's merchandising group ids are never compared, since those change on their own with no real product change. Turn on "Emit unchanged" or "Emit expired" only when you also want those products returned . State is kept separately for each search/URL/filter setup; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the search/URL and filter settings; different setups then never mix state with each other.

## `baselineDatasetId` (type: `string`):

Optional. Pick the dataset of an earlier full run of this Actor to use as your starting point, so your first incremental run returns only products that changed since then instead of the whole catalogue again. Pick the dataset unedited: it must be this Actor's own product output. Only used on the first run for a state key; ignored once that state key already tracks products. Cannot be combined with Resume from a previous run. If the dataset is old, everything that changed since is returned as UPDATED or NEW.

## `earlierHistoryStoreId` (type: `string`):

Optional. Pick the saved-history store of the Kmart Australia Scraper (named kmart-com-au-incremental-state) so your first Lite run for a State key, or for the same search settings, continues from the history that scraper already tracked, instead of returning the whole catalogue as NEW. The store is only read, never changed. Only used on the first run for a state key; ignored once that state key already tracks products, or when Start from an existing dataset or Resume is set.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return products that have not changed since the last run, marked UNCHANGED. This returns extra rows you already have, so leave it off unless you specifically want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return products that were present in a previous run but are no longer found, marked EXPIRED. Only produced after a complete scan of the tracked search or URLs, not when Max products or Max pages capped it or when Resume was used. This returns extra synthetic rows, so leave it off unless you need expiry tracking.

## `changeScope` (type: `string`):

All fields (default): any change to the product record, except the always-ignored review fields, returns an UPDATED row. Price and availability only: only price changes (including each variant's price) and stock changes (national and per variant, limited to Tracked states when you pick some) return an UPDATED row; changes to descriptions, images, badges, shipping or other details never do. Price and local store availability: only price changes (including each variant's price) and in-stock or Click & Collect changes at the stores near your Store postcodes return an UPDATED row; Kmart's per-state and national stock flags are not compared (needs Store postcodes). Selling price and availability only: like Price and availability only, but a price change counts only when the selling price (currentPrice, for the product or a variant) moves; Kmart's scheduled or expired promotion entries, was prices and savings never return a row on their own. Changing this option, Tracked states or Fetch reviews on a search with no State key continues from that search's saved baseline instead of starting over. In every option, a store or Click & Collect availability change at your selected stores returns an UPDATED row when Store postcodes is set; unit counts and stock levels alone never do.

## `compactUpdates` (type: `boolean`):

Off by default. When on, UPDATED rows (and EXPIRED rows) are short: product id, url, name, current price and stock, plus priceChanges and variantChanges showing the old and new value of each moved price or stock field per variant. NEW rows always carry the complete product record. Review text is not included in compact rows and consumes no review event fee.

## `expireAfterMissedScans` (type: `integer`):

Only used with Emit expired products. A product is marked EXPIRED only after it has been missing from this many full scans in a row (default 1). Raise it (e.g. 3) so a product that briefly drops out of a category listing is not reported as gone. A product that comes back resets the count. Stock status itself is reported through the availability fields, not through EXPIRED.

## `ignoreFieldsForChanges` (type: `array`):

Optional. Field names to exclude from UPDATED change detection, in addition to the built-in handling (reviews, review stats, the average rating and group ids already never trigger a false UPDATED, since those change on their own with no real product change). Use this if another field in your setup turns out to be noisy, e.g. a field that rotates without the product itself changing. To ignore a field inside each variant while still tracking variant prices and stock, use a dotted name such as variations.image (also variations.colour, variations.size, variations.isDefault, variations.apn). Ignoring variations itself would also hide variant price and stock changes.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify then Settings then API & Integrations, then select it here. Notion gets a page-per-item export; other connectors get a best-effort write. Leave empty to skip. Supported: Notion, Linear, Airtable, Apify.

## `notionParentPageUrl` (type: `string`):

URL or id of the Notion page under which item pages are created. Required only for the Notion export.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "searchTerms": [
    "towel"
  ],
  "specialsCategory": "",
  "urls": [
    "https://www.kmart.com.au/toys/",
    "https://www.kmart.com.au/womens/",
    "https://www.kmart.com.au/toys/?page=2",
    "https://www.kmart.com.au/catalogue/",
    "https://www.kmart.com.au/clearance/",
    "https://www.kmart.com.au/brand/target/",
    "https://www.kmart.com.au/search/?searchTerm=towel",
    "https://www.kmart.com.au/product/madison-bath-towel-ocean-42442370/",
    "https://www.kmart.com.au/category/home-and-living/home-decor/",
    "https://www.kmart.com.au/category/online-exclusives/"
  ],
  "basketItems": [
    {
      "url": "https://www.kmart.com.au/product/madison-bath-towel-ocean-42442370/",
      "quantity": 2
    }
  ],
  "sortBy": "relevance",
  "includeMarketplace": false,
  "fetchReviews": true,
  "maxReviews": 20,
  "maxItems": 20,
  "maxPages": 0,
  "includeClickAndCollect": true,
  "verifyOnlineDelivery": false,
  "returnDeliveryAnswers": false,
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "changeScope": "all",
  "compactUpdates": false,
  "expireAfterMissedScans": 1,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `reviews` (type: `string`):

No description

## `variants` (type: `string`):

No description

## `changes` (type: `string`):

No description

## `stores` (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 = {
    "mode": "search",
    "searchTerms": [
        "towel"
    ],
    "urls": [
        "https://www.kmart.com.au/toys/",
        "https://www.kmart.com.au/womens/",
        "https://www.kmart.com.au/toys/?page=2",
        "https://www.kmart.com.au/catalogue/",
        "https://www.kmart.com.au/clearance/",
        "https://www.kmart.com.au/brand/target/",
        "https://www.kmart.com.au/search/?searchTerm=towel",
        "https://www.kmart.com.au/product/madison-bath-towel-ocean-42442370/",
        "https://www.kmart.com.au/category/home-and-living/home-decor/",
        "https://www.kmart.com.au/category/online-exclusives/"
    ],
    "basketItems": [
        {
            "url": "https://www.kmart.com.au/product/madison-bath-towel-ocean-42442370/",
            "quantity": 2
        }
    ],
    "proxy": {
        "useApifyProxy": true
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "changeScope": "all",
    "compactUpdates": false,
    "expireAfterMissedScans": 1,
    "ignoreFieldsForChanges": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/kmart-au-scraper-lite").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 = {
    "mode": "search",
    "searchTerms": ["towel"],
    "urls": [
        "https://www.kmart.com.au/toys/",
        "https://www.kmart.com.au/womens/",
        "https://www.kmart.com.au/toys/?page=2",
        "https://www.kmart.com.au/catalogue/",
        "https://www.kmart.com.au/clearance/",
        "https://www.kmart.com.au/brand/target/",
        "https://www.kmart.com.au/search/?searchTerm=towel",
        "https://www.kmart.com.au/product/madison-bath-towel-ocean-42442370/",
        "https://www.kmart.com.au/category/home-and-living/home-decor/",
        "https://www.kmart.com.au/category/online-exclusives/",
    ],
    "basketItems": [{
            "url": "https://www.kmart.com.au/product/madison-bath-towel-ocean-42442370/",
            "quantity": 2,
        }],
    "proxy": { "useApifyProxy": True },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "changeScope": "all",
    "compactUpdates": False,
    "expireAfterMissedScans": 1,
    "ignoreFieldsForChanges": [],
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/kmart-au-scraper-lite").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 '{
  "mode": "search",
  "searchTerms": [
    "towel"
  ],
  "urls": [
    "https://www.kmart.com.au/toys/",
    "https://www.kmart.com.au/womens/",
    "https://www.kmart.com.au/toys/?page=2",
    "https://www.kmart.com.au/catalogue/",
    "https://www.kmart.com.au/clearance/",
    "https://www.kmart.com.au/brand/target/",
    "https://www.kmart.com.au/search/?searchTerm=towel",
    "https://www.kmart.com.au/product/madison-bath-towel-ocean-42442370/",
    "https://www.kmart.com.au/category/home-and-living/home-decor/",
    "https://www.kmart.com.au/category/online-exclusives/"
  ],
  "basketItems": [
    {
      "url": "https://www.kmart.com.au/product/madison-bath-towel-ocean-42442370/",
      "quantity": 2
    }
  ],
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "changeScope": "all",
  "compactUpdates": false,
  "expireAfterMissedScans": 1,
  "ignoreFieldsForChanges": []
}' |
apify call abotapi/kmart-au-scraper-lite --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/kmart-au-scraper-lite"
        }
    }
}
```

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/ACDXEAroZfvm74TYh/builds/9qQrC1TlVKphLEVg4/openapi.json
