# BIG W Marketplace Scraper Lite (`abotapi/bigw-marketplace-scraper-lite`) Actor

Scrape BIG W products & specials from bigw.com.au: name, title, brand, seller, price, was/original price, discount %, offer label, unit price, images, specs, GTIN/EAN, variants, rating & reviews. Filter by specials (on-special, clearance, flash deals), keyword, category & price, or paste URLs.

- **URL**: https://apify.com/abotapi/bigw-marketplace-scraper-lite.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

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

## BIG W Marketplace Scraper Lite: Products, Specials & Reviews

BIG W Marketplace Scraper Lite turns bigw.com.au into a clean, structured product feed. Get third-party marketplace-seller listings (and optionally BIG W's own range) with price, was-price, discount, offer labels, stock, images, specifications, identifiers and category, plus customer reviews with an aggregate rating summary. Search by keyword with brand, category, price, rating and specials filters, or paste product and search links directly, then export to JSON, CSV or Excel, or pull the results straight into your app through the API. All prices are in Australian dollars (AUD).

### Why This Scraper?

- **Two ways to find products.** Search by keyword with rich filters, or paste product and search URLs directly. No need to build search parameters by hand.
- **Marketplace-seller focus.** Defaults to third-party BIG W Marketplace sellers only, with an option to also include BIG W's own range for a full-catalogue view.
- **Real specials detail.** Was-price, discount amount and percent, the site's own offer label (such as "1/2 Price" or "35% OFF"), clearance flags and per-unit pricing, all left empty rather than invented when the site shows no offer.
- **Full listing depth.** Images, specifications, variant and colour/size matrices, GTIN/EAN/MPN identifiers, fulfilment and stock detail come back on every record.
- **Reviews on demand.** Attach customer reviews and an aggregate rating summary per product, capped to the number you need. Reviews consume additional platform usage only when you turn them on; there is no enrichment event fee.
- **Unlimited catalogue walking by default.** Pagination has no artificial cap: a search or URL walk stops only once the storefront's own result count is reached or a page repeats with nothing new.
- **Built for schedules.** Incremental mode returns only new and changed products on recurring runs, and a run that is refused fails loudly instead of returning an empty dataset.

### Use Cases

- **Price and deal tracking:** monitor specials, clearance and price drops across BIG W Marketplace sellers for repricing or deal-alert tools.
- **Marketplace seller research:** compare third-party sellers against BIG W's own range by brand, category or price band.
- **Catalogue and comparison feeds:** pull structured product data (identifiers, images, specifications, variants) into your own catalogue, price-comparison site or feed.
- **Review and reputation analysis:** collect customer reviews and rating distributions to score sellers or products over time.
- **Recurring monitoring:** schedule the actor against a fixed search or product list and get only what changed since last time.

### Data You Get

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

| Field | Example |
| --- | --- |
| `articleId` | `"7700001111"` |
| `gtin` / `ean` / `mpn` | `"9312345678901"` / `"9312345678901"` / `"SC-SHELF-01"` |
| `name` / `title` | `"Sample Garage Shelving Unit"` / `"SampleCo Sample Garage Shelving Unit"` |
| `brand` | `"SampleCo"` |
| `sellerType` / `sellerName` | `"Marketplace Seller"` (also `"BIG W"`) / `"Sample Seller Co"` |
| `isMarketplace` / `productChannel` | `true` / `"MARKETPLACE"` |
| `price` / `wasPrice` | `45.0` / `60.0` |
| `saving` / `savingsPercent` | `15.0` / `25` |
| `isOnSpecial` / `priceLabel` | `true` / `"Special"` |
| `rrp` / `unitPrice` / `pricePerUnitPrice` / `pricePerUnitQuantity` / `pricePerUnitUnit` | `65.0` / `{"price": 2.25, "unit": "100 G"}` / `2.25` / `100` / `"G"` (the last three are a flat copy of `unitPrice`, when BIG W shows one) |
| `currency` | `"AUD"` |
| `condition` / `listingStatus` | `"NEW"` / `"ACTIVE"` |
| `inStock` / `maxQuantity` / `stockStatus` / `summary` | `true` / `5` / `"IN_STOCK"` / short feature blurb |
| `category` / `categories` / `categoryPath` | `"Home & Garden"` / `["Home & Garden", "Storage"]` / `"Home & Garden > Storage > Shelving"` |
| `imageUrl` / `images` | image link / full gallery array |
| `variants` / `colours` / `sizes` | variant matrix array / `["Black", "White"]` / `["Small", "Large"]` |
| `specifications` | `{"Material": "Steel", "Assembly required": "Yes"}` |
| `description` | `"A sample product description."` |
| `url` | link to the product page |
| `fulfilment` | `{"logisticType": "DIRECT_SHIP", "delivery": true, "collection": false}` |
| `rating` | `4.5` |
| `reviews` / `reviewStats` | review array / `{"reviewCount": 40, "averageRating": 4.5}` (when reviews are on) |
| `changeType` / `changedFields` / `firstSeenAt` / `lastSeenAt` | `"UPDATED"` / `["price", "wasPrice"]` / timestamps (incremental mode only) |
| `previousPrice` | `49.0`: the price before this run, on UPDATED rows when the price moved (incremental mode only) |
| `priceChanges` / `variantChanges` | `{"price": {"old": 49.0, "new": 45.0}}` / `[{"code": "7700001112", "size": "M", "change": "CHANGED", "changes": {"listingStatus": {"old": "ListedSellable", "new": "Delisted"}}}]` (compact update rows only) |
| delivery fields | `deliveryPostcode`, `standardDeliveryAvailable`, `sameDayDeliveryAvailable`, arrival window, `variantDelivery`, `deliveryChanges` (when **Verify home delivery** is on, see below) |

A product with no offer active still returns `wasPrice`, `saving`, `savingsPercent` and `priceLabel` as empty rather than fabricated. Products with no reviews return an empty `reviews` array once reviews are turned on.

### How to Use

1. Pick a **mode**: `search` (keyword and filters) or `url` (paste product or search links).
2. Fill in the fields for that mode, and switch on **Fetch customer reviews** if you want them.
3. Set **Max products** to control run size and cost, then click **Start**.
4. Download the dataset as JSON, CSV or Excel, or read it through the API.

**Search by keyword with a specials filter:**

```json
{
  "mode": "search",
  "queries": ["garage shelving"],
  "specialsCategory": "special",
  "marketplaceOnly": true,
  "maxItems": 20
}
```

**Paste a product link and a search link:**

```json
{
  "mode": "url",
  "urls": [
    "https://www.bigw.com.au/product/sample-item/p/1234567",
    "https://www.bigw.com.au/search?text=kettle",
    "https://www.bigw.com.au/toys/lego/c/6822101"
  ]
}
```

Category links work like a filtered browse of that category; a link the actor does not recognise is reported with a warning and skipped.

**Search with a price range and reviews:**

```json
{
  "mode": "search",
  "queries": ["kettle"],
  "minPrice": 20,
  "maxPrice": 150,
  "fetchReviews": true,
  "maxReviewsPerProduct": 10,
  "maxItems": 30
}
```

**Daily price, availability and delivery watch for postcode 4209 (short change rows):**

```json
{
  "mode": "search",
  "queries": ["kettle"],
  "soldBy": "bigw",
  "deliveryPostcode": "4209",
  "verifyHomeDelivery": true,
  "proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "AU" },
  "incrementalMode": true,
  "changeScope": "sellingPriceAndStock",
  "compactUpdates": true,
  "emitExpired": true,
  "expireAfterMissedScans": 2,
  "maxItems": 0
}
```

`"soldBy": "bigw"` keeps only products sold by BIG W itself and excludes every third-party marketplace seller. (`"marketplaceOnly": false` is not the same: it returns BIG W's own range **and** marketplace listings.)

The first run returns every product in full (NEW). Each later run returns only products whose selling price, stock or listing status, size/colour variants, or delivery availability to 4209 changed, as short rows with the old and new values; products that left the search for two complete scans in a row come back once as EXPIRED; unchanged products are not returned or billed.

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/bigw-marketplace-scraper-lite").call(run_input={"mode": "search", "queries": ["garage shelving"]})
for product in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(product["name"], product["price"], product["currency"])
```

JavaScript:

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

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

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

#### Max products, Max pages, sort order and Resume

The store's search serves at most 2,000 results per search; when it reports more, the run log warns and the run summary lists the search in `searchesCappedAtMaxResults`. Split such a search with a category, brand or price range filter to cover the rest. **Max pages** defaults to `0` (walk every page): a search or URL walk stops naturally once the storefront's own result total is reached or a page repeats with no new products, so there is no artificial page cap unless you set one. **Max products** caps the overall run.

**Resume** (`resumeFromRunId`): pass a prior run's ID (or dataset ID) and this run seeds its de-duplication set from that run's dataset, so it skips products already collected there and returns only a delta. This works reliably for pasted **product links**. For a **search or pasted search link** it is much weaker than it sounds: a listing walk stops at the first page whose products were all already collected, and the previously collected products count for that check. So if the earlier run collected every product on the first page of a search, the resumed run stops on that first page and returns nothing more from it, even when later pages hold products the earlier run never reached. For recurring top-ups of a search, use **Incremental mode** instead.

**Sort orders other than Relevance / Newest first** read the listing first (up to Max products, rounded up to whole pages) and push only once it is sorted. "Highest rated" is sorted by this actor, not by the site, so with a Max products cap it returns the highest-rated products among the first pages of the relevance listing, not the highest-rated products overall.

#### Incremental mode (recurring monitoring)

Turn on **`incrementalMode`** to run the same search or URL list on a schedule and get only what changed. Every product is classified against the last run of the same search/filter setup:

- **NEW**: not seen before.
- **UPDATED**: a real catalogue field changed (`changedFields` lists which). Price, was-price, saving, specials flags, stock, condition, listing status, fulfilment and the variant/colour/size matrix all count; the aggregate `rating` and the `reviews`/`reviewStats` fields are driven by other customers and deliberately excluded from change detection, so a new review alone never trips UPDATED.
- **UNCHANGED**: nothing changed (suppressed, not returned or billed, unless `emitUnchanged` is on).
- **REAPPEARED**: was gone, is back.
- **EXPIRED**: was tracked, no longer found. Only produced when `emitExpired` is on and the run judges that it reached the end of every keyword/URL in this search, with no `resumeFromRunId` and without hitting Max products or Max pages. That judgement can be wrong in the cases listed below, so a live product can be reported EXPIRED.

State is scoped automatically to your exact mode/queries/urls/filters, so two different searches never share a baseline, unless you pin **`stateKey`** yourself to share one on purpose. `emitUnchanged` and `emitExpired` are off by default because they return, and bill, rows you already have.

**What counts as a change (`changeScope`):**

| Value | An UPDATED row is returned when |
| --- | --- |
| `all` (default) | any product field changes, except reviews and the rating |
| `priceAndStock` | a price field (price, was price, RRP, saving, special and clearance flags) or an availability field (in stock, listing status, deliverable, collectable) changes, or a size/colour variant is added, removed or changes its listing status |
| `sellingPriceAndStock` | as `priceAndStock`, but only the selling price (`price`) counts as a price change; was price, RRP, savings and promotion flags never return a row on their own |

BIG W lists size and colour variants with their own code and listing status, not their own price, so variant changes are availability changes. With **Verify home delivery** on, a delivery availability change returns an UPDATED row in every option (see below). Changing `changeScope` or **Fetch customer reviews** on a search with no `stateKey` continues from that search's saved state instead of starting over, so switching never returns the whole set as NEW.

**Compact update rows (`compactUpdates`, off by default):** UPDATED and EXPIRED rows carry only the article id, url, name, brand, seller type, current price and stock, `previousPrice`, `priceChanges` (old and new value of each moved price or availability field) `variantChanges` (each variant added, removed or changed) and, with **What counts as a change** set to All fields only, `otherChanges` (old and new value of every other field named in `changedFields`, for example a description edit or a reordered variant list; `null` when nothing else moved). In the price scopes the key is not present. A compact UPDATED row always shows what moved in at least one of these sections. A variant listed without a code is reported under `#<position>` (for example `#0`), and a code that appears twice in one product's variant list is reported as `<code>#1` for its second occurrence. With delivery checks on they also carry the delivery answer and `deliveryChanges` / `variantDeliveryChanges`. NEW rows are always complete. Review text is not fetched for compact rows.

**Missing products (`emitExpired`, `expireAfterMissedScans`):** a tracked product is returned as EXPIRED once it has been missing from `expireAfterMissedScans` complete scans in a row (default `1`; raise it so a product that briefly drops out of a search is not reported as gone). For a pasted product link, a product the store no longer lists (it answered and the id is not there) counts as missing; a lookup that could not be read, or that the store answered with an error or with a result page whose own counts do not add up, is never treated as missing: none of that page's products are used and the run is an incomplete scan, so nothing expires that run (the same applies to such a page in a search).

**Start from an existing dataset (`baselineDatasetId`):** pick the dataset of an earlier run of this Actor and the first incremental run for a state key compares against it, returning only products that changed since. Compact update rows and EXPIRED rows in that dataset are skipped, and answered delivery checks in it become the delivery baseline. It is ignored once the state key already tracks products, cannot be combined with `resumeFromRunId`, and a dataset that is not this Actor's unedited output, or too large to track as one baseline (roughly more than 6,000 products, to stay within the default memory), is refused before anything is collected.

**Coming from the BIG W Marketplace Scraper? (`earlierHistoryStoreId`, optional):** if you tracked the same State key (or the same search settings) there, pick that scraper's history store (`bigw-com-au-incremental-state`) in "Continue from the BIG W Marketplace Scraper's history" and the first Lite run continues from that saved history (including the last delivery answers), so you are not given the whole set as NEW again. Your earlier history is only read, never changed, and nothing needs to be copied or run. The run stops with a message, before anything is scraped, when the picked store is not that scraper's history store, does not hold BIG W products, cannot be read, is too large, or holds saved history for this search in an unexpected format (nothing is skipped or partly imported); when it simply has nothing saved for this State key or these search settings, the run says so and starts fresh. It is ignored once the key already tracks products, and when Start from an existing dataset or Resume is set. A large history needs a matching run memory: at the default 256 MB about 6,600 tracked products can be continued from; for more, the run stops before scraping and says which memory to set (keep that memory for the later runs too).

A few edge cases worth knowing before you rely on this for billing-sensitive monitoring:

- **Max products counts returned rows.** EXPIRED rows count too: they are returned only up to what is left of Max products, and the rest stay tracked and are returned on a later run. On Relevance and Newest first, unchanged products are compared and not returned without using up Max products, so the walk keeps going until the cap is filled with NEW, UPDATED or REAPPEARED rows; a capped run is never a complete scan, so it never returns EXPIRED rows. On the other sort orders the listing is cut to Max products before products are compared, so products beyond the cap are not checked that run. **For incremental monitoring, set Max products to `0`.**
- **Bootstrapping incremental mode from `resumeFromRunId`.** On a first incremental run that also uses `resumeFromRunId`, each product is seeded from its row in the resumed dataset, so the next run returns only products that really changed since. A product whose only row there is a compact update row has no full record to seed from and is returned once as UPDATED on the next run that reaches it. The bootstrap run itself is also subject to the resume limitation above, so it may return little or nothing from a search.
- **Runs that hit their timeout, migrate or are resurrected keep their state.** A run stops by itself shortly before its timeout (75 seconds, or a quarter of its run time for a short timeout) so that it can save what it returned (the scan then counts as incomplete: no EXPIRED rows and no missed scan are counted, and products it did not reach keep their previous state for the next run); environment variable `BIGW_STOP_BEFORE_TIMEOUT=0` switches this off. A migrated or resurrected run puts the rows it had already returned back into the saved state before it continues, so the next scheduled run does not return (or bill) them again, and it never overwrites a newer state saved by another run in between. If it cannot read those rows back it stops without returning anything more (resurrect it again later). The one case this cannot cover is a run that crashes without warning (for example out of memory) and is never resurrected: its returned rows can come back once on the next run. A restarted run treats the rows already in its dataset as delivered even when it was stopped before its first progress record was saved, never returns them a second time, and counts them against Max products. One case to know: with compact update rows in a price scope, a product returned as UPDATED just before a restart keeps its earlier non-price fields (description, images) in the saved state, because a compact row in those scopes does not carry them; switching that search to All fields later can then return such a product once as UPDATED for those fields.
- **A shared `stateKey` mixes completeness across searches.** If you deliberately point two differently-configured searches at the same `stateKey`, a run that fully scans only one of them marks products that only the other search finds as EXPIRED, even though they are still live. Use distinct `stateKey` values per search unless you specifically want this.
- **Very similar keywords or URLs in one run can end each other's walk early.** If earlier keywords or URLs in the same run already collected every product on a later keyword's first page, that keyword stops after that page. Its remaining pages are then unread, so the run does not count as a complete scan and returns no EXPIRED rows.
- **A pasted search URL that starts on a later page.** URL mode walks forward only from the page number in the link you paste, so earlier pages are never read and such a run never returns EXPIRED rows for that link. Paste search links starting at page 1 (or use Search mode) if you use `emitExpired`.
- **EXPIRED needs a fully seen result list.** A product is returned as EXPIRED only after a scan that saw every product the store reported for the search: every page complete, the result count unchanged from page to page, and as many different products as the store reported. The store's search sometimes shows the same product on two pages (and skips another) or changes its count while a run reads it; such a run returns no EXPIRED rows and counts no missed scan, and a later run that sees the whole list does.

#### Home delivery to a postcode

Set `deliveryPostcode` (for example `4209`) and turn on `verifyHomeDelivery` to get, for every returned product, the delivery answer for that postcode. It works for BIG W-sold and marketplace products alike (marketplace arrival estimates are usually longer).

| Field | Meaning |
| --- | --- |
| `deliveryPostcode`, `deliverySuburb` | The postcode checked and the first suburb listed for it. |
| `standardDeliveryAvailable` | Standard delivery is offered to the postcode. |
| `standardDeliveryEtaFrom`, `standardDeliveryEtaTo` | Estimated arrival window (dates). |
| `sameDayDeliveryAvailable` | Same-day delivery is offered. This is a separate method: it is often `false` while standard delivery is `true`, so `false` here never means the product cannot be delivered. |
| `minDeliveryFeeCents` | Lowest delivery fee, in cents. |
| `deliveryChecked` | `true` when the answer was read. `null` when the check could not be read: every delivery field is then `null` (unknown), never "unavailable". |
| `variantDelivery` | For a product answered per size or colour: one entry per answered variant with its own standard and same-day availability, arrival window and fee. `null` otherwise. |

The store's response does not give a reliable stock count, so none is reported. The answer is read live for each product once per run. For delivery checks, set Proxy configuration to proxy group: RESIDENTIAL, country AU. The share of answered products can vary from run to run, and a few products can come back unknown. On a run that uses Apify Proxy with proxy group: RESIDENTIAL, when the default connection is unavailable, the delivery checks of the run move to a backup connection for the rest of the run (`allowBackupConnection`, on by default), and the log says "Served over the backup connection (the default connection was unavailable)." The backup connection is slower and uses more of your proxy allowance per check, about 3 seconds more per product; a very large run may reach its run timeout, in which case the products not yet checked are returned with an unknown delivery answer and the run ends normally with a message saying so. Turn `allowBackupConnection` off to keep the default connection only. If your account cannot use the backup connection, or it stops answering, the checks continue on the default connection. A product the store treats as a group of variants (for example a T-shirt in several sizes, or a kettle in several colours) is answered per variant rather than for the product itself: each answered size or colour is returned in `variantDelivery` (code, colour or size, standard and same-day availability, arrival window, fee), while the product-level delivery fields stay `null` because the variants can differ. Unknown means `deliveryChecked` is `null` and every delivery field is `null`, never "unavailable". After many consecutive failed checks with nothing answered the checks stop, and when every check fails the run stops with no products and a message explaining why.

In incremental mode the delivery answers are not part of a product's change detection (arrival dates and the fee move on their own). If standard or same-day availability flips for a product, it is returned as UPDATED with `deliveryChanges` listing the flip (`{"standardDeliveryAvailable": {"from": true, "to": false}}`) and `"deliveryChanges"` in `changedFields`; a flip for one size or colour is listed in `variantDeliveryChanges` with that variant's code, colour or size. Only answers read in both runs are compared: a check that could not be read is no change, keeps the last known answer for the next comparison, and returns nothing. The same holds for each method on its own (an answer that omits same-day delivery keeps the last known same-day value) and for each size or colour, and the last known answers are kept through runs with **Verify home delivery** off. Changing the postcode starts a fresh comparison and returns nothing extra.

**First known answer.** When a product (or one of its sizes or colours) was last returned with an unknown answer, or with the same-day method missing, and a later run reads it, that run returns the product once as UPDATED with `"deliveryFirstKnown"` in `changedFields` and `{"from": null, "to": true}` (or `false`) in `deliveryChanges` / `variantDeliveryChanges`. This is one extra billed row per such product, once. After that only real flips between two known answers are returned. A product that was first seen with delivery checks off, or under another postcode, starts a fresh comparison and returns nothing extra.

**Reading the delivery answer reliably.** Each check that is not answered (the connection refused, a page that is not a delivery answer, a server error or a rate limit) is tried again on a new connection after a short pause, within the same per-product limit; a product that keeps answering that way is marked unknown after three tries, and a product the store does not have (404) is final. The run log and the status message list the unknown checks by cause, and the run summary (below) gives the totals.

**How to import the delivery fields.**

- `standardDeliveryAvailable` (and `sameDayDeliveryAvailable`): `true` or `false` is a confirmed answer; `null` is unknown, never "unavailable".
- `deliveryChecked`: `true` only when the product itself was answered; `null` otherwise, including size and colour groups whose answers are in `variantDelivery`.
- `sameDayDeliveryAvailable` `null` with `deliveryChecked` `true`: the same-day method was missing from the answer.
- A size or colour code missing from `variantDelivery`: unknown for that variant.
- Variant codes of the form `#0`, `#1` (a variant listed without a code, by its position) or `<code>#1` (the second occurrence of a repeated code) in `variantChanges` are labels made by this Actor, not BIG W codes.
- `deliveryChanges` / `variantDeliveryChanges` compare two known answers, except a first known answer, which has `"from": null`.
- Arrival dates and the delivery fee never return a row on their own.
- An unchanged product is not returned again, so keep the last value your import saw. Delivery checks add requests to your connection usage; they add no separate charge beyond the usual result rows.

### 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 record, 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, Settings, 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` (keyword and filters) or `url` (paste product/search links). |
| `queries` | array | (none) | Keywords to search, one per entry (for example "piano keyboard"). Each keyword is searched separately. Leave empty to browse the whole marketplace. |
| `urls` | array | one example per link shape | Product, search or category URLs to scrape: a `/product/<name>/p/<id>` or `/p/<id>` product link, a `/search?text=...` link (optionally `&page=N`, 1-based; the `m.` mobile host works), or a `/<dept>/<sub>/c/<id>` category link. Multiple URLs supported. **Behaviour change:** in URL mode with this field left untouched, the actor now scrapes the example links (a search, a page-2 search, a mobile-host search, one product and one category) instead of failing for lack of URLs. |
| `marketplaceOnly` | boolean | `true` | Keep only third-party marketplace-seller listings; turning it off returns BIG W's own range **and** marketplace listings. To get BIG W's own range only, set `soldBy` to `bigw` instead. |
| `soldBy` | string | (not set) | Optional: `all`, `bigw` (BIG W's own range) or `marketplace`. When set it overrides `marketplaceOnly`; when not set `marketplaceOnly` decides as before. |
| `fulfilment` | string | (not set) | Optional: `pickup` keeps only products that can be collected in store. Marketplace products are never collectable. |
| `brand` | string | (none) | Keep only products whose brand matches this value. |
| `category` | string | (none) | Restrict results to a BIG W category: its name as shown on the site (looked up on the store; an unknown name stops the run with an error) or its id (the trailing number in a category URL). |
| `specialsCategory` | string | `""` (Any) | Show only products in one of BIG W's specials views: on special/reduced, clearance, flash deal, lowest price in 7 or 14 days, or new arrivals. |
| `deal` | string | (none) | Advanced: filter by a raw BIG W deal label if the selector above doesn't list it. Combined with it when both are set. |
| `sortBy` | string | `relevance` | `relevance`, `priceAsc`, `priceDesc`, `ratingDesc`, `nameAsc`, or `newDesc`. |
| `minPrice` | integer | (none) | Only keep products priced at or above this amount (AUD). |
| `maxPrice` | integer | (none) | Only keep products priced at or below this amount (AUD). |
| `minRating` | integer | (none) | Only keep products with an average customer rating at or above this value (1 to 5). |
| `includeOutOfStock` | boolean | `true` | Include out-of-stock products; turn off to keep only in-stock ones. |
| `fetchReviews` | boolean | `false` | Also collect customer reviews and an aggregate rating summary per product. |
| `maxReviewsPerProduct` | integer | `20` | Cap on reviews collected per product when `fetchReviews` is on. `0` = the hard limit of 1000 reviews per product, enforced in code (maximum 1000). |
| `maxItems` | integer | `20` | Maximum number of products to return across the whole run. `0` = unlimited. |
| `maxPages` | integer | `0` | Safety cap on result pages walked per keyword/URL. `0` = unlimited: the walk still stops naturally at the storefront's own end of results. |
| `deliveryPostcode` | string | (none) | Four-digit postcode (for example `4209`) to check home delivery for. Needs `verifyHomeDelivery`; setting one without the other stops the run with a clear message. |
| `verifyHomeDelivery` | boolean | `false` | Check, for every returned product, whether home delivery to the postcode is offered. Adds one request per product. |
| `allowBackupConnection` | boolean | `true` | Home delivery checks only, on runs that use Apify Proxy with proxy group: RESIDENTIAL: when the default connection is unavailable, the checks continue over the backup connection, which is slower and uses more of your proxy allowance per check (about 3 seconds more per product). Turn off to keep the default connection only. |
| `resumeFromRunId` | string | (none) | ID of a previous run (or dataset) of this actor. Already-collected products are skipped, so this run returns only new ones (a delta). For searches, see the Resume note in How to Use. |
| `incrementalMode` | boolean | `false` | Return only new and changed products on scheduled runs of the same search. |
| `stateKey` | string | (none) | Name a monitoring campaign to keep its state stable, or share state across differently-configured runs on purpose. |
| `emitUnchanged` | boolean | `false` | Also return (and bill) products unchanged since the last run, marked UNCHANGED. |
| `emitExpired` | boolean | `false` | Also return (and bill) products no longer found, marked EXPIRED. Only produced after a complete scan (see Incremental mode above). |
| `ignoreFieldsForChanges` | array | `[]` | Incremental mode only. Field names (or dotted paths such as `fulfilment.eta`) that never count as a change: they stay in the output but are left out of change detection and `changedFields`. Changing the list does not re-report tracked products. |
| `changeScope` | string | `all` | What counts as a change: `all`, `priceAndStock` or `sellingPriceAndStock` (see Incremental mode above). |
| `compactUpdates` | boolean | `false` | Return UPDATED and EXPIRED rows as short rows with old and new values (`priceChanges`, `variantChanges`). |
| `expireAfterMissedScans` | integer | `1` | With `emitExpired`: complete scans in a row a product must be missing before it is returned as EXPIRED (1 to 30). |
| `baselineDatasetId` | string | (none) | Dataset of an earlier run of this Actor to compare the first incremental run against. |
| `earlierHistoryStoreId` | string | (none) | Incremental mode only. Pick the BIG W Marketplace Scraper's saved-history store (`bigw-com-au-incremental-state`) so the first Lite run for a State key, or for the same search settings, continues from that history instead of returning everything as NEW. Read only; used only while the key has no saved state, never with `baselineDatasetId` or Resume. |
| `proxy` | object | Apify Proxy | Connection settings. |
| `mcpConnectors` | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
| `notionParentPageUrl` | string | (none) | Notion connector only: page under which records are created. |
| `maxNotifyListings` | integer | `50` | Cap on items written to each connector per run. |

#### URL mode

| URL shape | Result | Default start |
|---|---|---|
| Product link (`/product/<name>/p/<id>`) or a bare numeric id (6+ digits) | One product | n/a |
| Search link (`/search?text=`, `searchTerm=` or `q=`, optional `&page=`) | Pages of results | The page in the link, otherwise page 1 |
| Category link (`/<dept>/<sub>/c/<id>`) | Pages of results for that category | Page 1 |
| Specials link (`deal`, `deals`, `special`, `specials` parameters) | Pages of specials | Page 1 |

The URL list is no longer empty by default: left untouched, URL mode scrapes the five example links (search, search page 2, mobile host, one product, one category). Replace or clear them for your own run. Links the actor cannot recognise are reported with a clear warning in the log instead of being skipped silently. A search link that starts on page 2 or later is never used to mark earlier products as expired in incremental mode.

#### Output views and reviews

The dataset has four views: Overview, Reviews (one row per review), Changes (incremental results with `changeType` and `changedFields`) and Delivery (delivery-check answers). Each run also stores a run summary under the `OUTPUT` key (see Run summary below the output example). With **Fetch customer reviews** on, `maxReviewsPerProduct` (default 20, maximum 1000, `0` = the 1000 hard limit) caps the reviews kept per product.

### Output Example

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

```json
{
  "articleId": "7700001111",
  "gtin": "9312345678901",
  "ean": "9312345678901",
  "mpn": "SC-SHELF-01",
  "barcodes": null,
  "name": "Sample Garage Shelving Unit",
  "title": "SampleCo Sample Garage Shelving Unit",
  "brand": "SampleCo",
  "sellerType": "Marketplace Seller",
  "sellerName": "Sample Seller Co",
  "productChannel": "MARKETPLACE",
  "isMarketplace": true,
  "condition": "NEW",
  "listingStatus": "ACTIVE",
  "url": "https://www.bigw.com.au/product/sample-item/p/7700001111",
  "price": 45.0,
  "wasPrice": 60.0,
  "rrp": 65.0,
  "saving": 15.0,
  "savingsPercent": 25,
  "isOnSpecial": true,
  "unitPrice": { "price": 2.25, "unit": "100 G" },
  "currency": "AUD",
  "priceLabel": "Special",
  "priceLabelType": "PERCENT_OFF",
  "clearance": false,
  "onlineOnlyPromotion": false,
  "promotions": [],
  "paymentOptions": ["Afterpay", "Zip"],
  "rating": 4.5,
  "description": "A sample product description.",
  "imageUrl": "https://www.bigw.com.au/medias/sample-image.jpg",
  "images": ["https://www.bigw.com.au/medias/sample-image.jpg"],
  "category": "Home & Garden",
  "categories": ["Home & Garden", "Storage"],
  "categoryPath": "Home & Garden > Storage > Shelving",
  "variants": null,
  "colours": ["Black", "White"],
  "sizes": null,
  "specifications": { "Material": "Steel", "Assembly required": "Yes" },
  "maxQuantity": 5,
  "deliverable": true,
  "collectable": false,
  "limitedFreeShipping": false,
  "inStock": true,
  "fulfilment": { "logisticType": "DIRECT_SHIP", "dsv": false, "delivery": true, "collection": false },
  "searchMode": "search",
  "source": "bigw.com.au"
}
```

**Run summary (`OUTPUT` key).** Written after the state is saved:

| Key | Meaning |
| --- | --- |
| `productsReturned` | product rows returned (NEW, UPDATED, REAPPEARED, UNCHANGED, or plain rows); EXPIRED rows are not included |
| `expiredReturned` / `rowsReturned` | EXPIRED rows returned / all rows returned |
| `productsScanned` / `reviewsReturned` | products looked at / reviews on returned rows |
| `scanComplete` | every search or URL was read to its proven end with no stop (the test EXPIRED detection uses) |
| `stateCommitted` | the incremental state was saved (`null` outside incremental mode) |
| `stoppedEarlyReason` | `maxTotalCharge`, `runTimeout`, `deliveryUnreachable`, `siteOffline`, `maxItems`, or `null` |
| `searchesCappedAtMaxResults` | searches where the store reports more results than it serves (see Max products, Max pages, sort order and Resume) |
| `deliveryChecksAttempted` | products whose delivery was looked up |
| `deliveryChecksAnswered` / `deliveryChecksAnsweredPerVariant` | answered for the product / answered per size or colour |
| `deliveryProductsWithUnread` / `deliveryUnreadByCause` | looked up but unknown / the same by cause |
| `deliveryCoverage` | answered share of the checks (product or per variant), `null` when checks are off |

`scanComplete` says nothing about delivery: a complete scan can still carry unknown delivery answers (see `deliveryCoverage`).

### Plan Requirement

The default Apify Proxy setting normally serves BIG W directly. If that connection does not answer, the actor switches to an alternate connection on its own (a residential connection, country AU, where your plan includes it). Apify free plans have no Apify proxy, so on a free plan the run uses a backup connection and prints the messages below. A paid Apify plan, or your own proxy URLs, gives the most dependable access.

What you will see in the run log:

- When the selected connection is unavailable: "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable. For residential access, upgrade at https://apify.com/pricing or supply your own proxy URLs."
- When the backup connection serves the run: "Served over the backup connection (the default connection was unavailable)."
- When the run fails with no results because the proxy is refused for the account, or residential access is unavailable and the backup also fails, or the pages could not be loaded, the run ends as failed with a message stating which of these happened, rather than an empty successful run.

Set Proxy configuration to proxy group RESIDENTIAL, country AU, to start on the residential connection directly.

### 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 Lite version has no enrichment or review event fees; fetching customer reviews and checking home delivery still consume platform resources. Use **Max products**, **Max pages**, **Max reviews per product** and the platform run limits to bound work. In incremental mode only returned rows are billed as product events (NEW, UPDATED, REAPPEARED, and UNCHANGED or EXPIRED when you turn those on); a compact update row is one returned row. A delivery change is billed only as the one row that reports it. Suppressed, unchanged or failed items are not charged. If you set a maximum total charge for a run and it is reached, the run stops there: products not returned yet (new, changed or expired) are not marked as delivered and come back on the next run. Two behaviours change how many rows are billed: a product whose delivery answer (or a size or colour's answer) becomes known for the first time after being returned as unknown is returned once more, as one billed UPDATED row; and products a run already returned before it hit its timeout, migrated or was resurrected are no longer returned and billed again by the next run.

#### Is it legal to scrape BIG W Marketplace?

This actor collects only publicly available product and review data. You are responsible for how you use it: follow BIG W's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product facts (price, brand, specifications) are generally not protected, but images, descriptions and 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, updated and reappeared products, and unchanged ones are not billed. Set **Max products** to `0` for these runs, and read the caveats in How to Use before relying on this for exact billing on capped, resumed, migrated or overlapping runs.

#### How do I get only products sold by BIG W, without marketplace sellers?

Set `"soldBy": "bigw"`. It overrides `marketplaceOnly` (which is on by default and keeps only marketplace sellers) and returns BIG W's own range only; every row's `sellerType` is `BIG W`. Turning `marketplaceOnly` off is not enough, because that returns both. Combine it with `verifyHomeDelivery` and `deliveryPostcode` (for example `"4209"`) for verified home delivery.

#### Why did marketplaceOnly change what I expected?

**Marketplace sellers only** is on by default, so a plain keyword search returns third-party seller listings only, not BIG W's own range. Turn it off to see both, or combine it with **Specials / offers** to browse deals across the whole catalogue.

#### Why did my run fail instead of returning an empty dataset?

If the site refuses every request, the run stops with a clear message so "no matches today" is never confused with "nothing could be read". Run it again in a few minutes. If only some keywords or URLs could be read, you still get what was found.

#### 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 results into Notion, Linear or Airtable.

### 🔗 Want more e-commerce data?

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

<table>
<tr><td>🛒 <a href="https://apify.com/abotapi/myer-au-scraper"><b>Myer Scraper</b></a><br>Scrape Myer (myer.com.au) department-store products: name, brand, price, was-price...</td><td>🛒 <a href="https://apify.com/abotapi/harvey-norman-scraper"><b>Harvey Norman Scraper</b></a><br>Scrape Harvey Norman Australia products: name, brand, price, was-price / discount...</td></tr>
<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/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></tr>
<tr><td>🥦 <a href="https://apify.com/abotapi/coles-au-scraper"><b>Coles AU Scraper</b></a><br>Scrape Coles.com.au grocery products and customer reviews. Search by keyword, browse...</td><td>🛒 <a href="https://apify.com/abotapi/bunnings-com-au-scraper"><b>Bunnings Scraper</b></a><br>Scrape bunnings.com.au products with full specifications, price, brand, stock, image...</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/bigw-marketplace-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`):

Choose 'search' to use keywords and filters, or 'url' to scrape specific product or search URLs you paste below.

## `queries` (type: `array`):

One or more keywords to search, for example 'piano keyboard' or 'garage shelving'. Each keyword is searched separately. Leave empty to browse the whole marketplace.

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

Product or search URLs to scrape, for example https://www.bigw.com.au/product/x/p/9900004603, https://www.bigw.com.au/search?text=piano (add \&page=2 to start on page 2; the m. mobile host works too) or a category link such as https://www.bigw.com.au/toys/lego/c/6822101. Multiple URLs supported. Left untouched, URL mode scrapes these examples.

## `marketplaceOnly` (type: `boolean`):

Keep only listings sold by third-party marketplace sellers (exclude items sold directly by BIG W). On by default.

## `soldBy` (type: `string`):

Optional. Who sells the products: all, BIG W only, or marketplace sellers only. When set it overrides 'Marketplace sellers only'; leave on 'Not set' to keep that toggle in charge.

## `fulfilment` (type: `string`):

Optional. 'Click and collect only' keeps products that can be collected in store. Marketplace products are never collectable, so combining it with marketplace sellers returns nothing.

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

Optional. Keep only products whose brand matches this value, for example 'Alpha' or 'Giantz'.

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

Optional. Restrict results to a BIG W category: either its name as shown on the site (e.g. LEGO), which is looked up on the store, or its id (the trailing number in a category URL, e.g. 6822101 in /toys/lego/c/6822101). A name that cannot be found stops the run with a clear error.

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

Optional. Show only products in one of BIG W's on-site specials views. 'On special / reduced' covers half-price and percentage-off deals; also clearance, flash deals, recent price drops and new arrivals. Leave as 'Any' for no specials filter. Combine with a keyword to find specials in a topic, or leave the keyword empty to browse all specials.

## `deal` (type: `string`):

Optional, advanced. Filter by a raw BIG W deal label, for example 'Clearance', 'Flash Deal' or 'Special'. Most users should use the 'Specials / offers' selector above instead. Combined with it when both are set.

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

Ordering applied to the collected results.

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

Optional. Only keep products priced at or above this amount (AUD).

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

Optional. Only keep products priced at or below this amount (AUD).

## `minRating` (type: `integer`):

Optional. Only keep products with an average customer rating at or above this value (1 to 5).

## `includeOutOfStock` (type: `boolean`):

Include products that are currently out of stock. On by default; turn off to keep only in-stock products.

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

Also collect customer reviews for each product (review text, star rating, author, date, pros/cons, photos) plus an aggregate rating summary. Adds requests per product. Reviews consume additional platform usage; there is no enrichment event fee.

## `maxReviewsPerProduct` (type: `integer`):

Cap on reviews collected per product when 'Fetch customer reviews' is on. Use 0 for the hard limit of 1000 reviews per product (enforced in code).

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

Maximum number of products to return across the whole run. Use 0 for unlimited.

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

Optional safety cap on result pages walked per keyword / URL. 0 = unlimited (default); the walk still stops naturally once the storefront's own result total is reached, a page repeats with no new products, or Max products is hit.

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

Four-digit postcode, for example 4209. Requires 'Verify home delivery'.

## `verifyHomeDelivery` (type: `boolean`):

Check delivery availability to the postcode above for every returned product. Off by default.

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

Apify Proxy is recommended for reliable results. On the free plan, coverage may be limited and some runs may return no results.

## `allowBackupConnection` (type: `boolean`):

Home delivery checks only, on runs that use Apify Proxy with proxy group: RESIDENTIAL. When the default connection is unavailable, the checks continue over the backup connection, which is slower and uses more of your proxy allowance per check (about 3 seconds more per product); very large runs may reach the run timeout, and the products not yet checked are then returned with an unknown delivery answer. Turn off to keep the default connection only (checks may then come back unknown).

## `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 normally return only NEW, UPDATED, and REAPPEARED products. Turn on "Emit unchanged" or "Emit expired" only when you also want those products returned (and billed). State is kept separately for each distinct search/filter setup (or by State key below). Off by default.

## `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 your search/filter settings - different searches then never mix state with each other.

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

Off by default. Turn on to also return products that have not changed since the last run, marked UNCHANGED. This returns - and bills - 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 once a run has fully scanned the tracked search - not when Max products or Max pages capped it, or when Resume was used. This returns - and bills - extra synthetic rows.

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

All fields (default): any change to the product record, except reviews and the rating, returns an UPDATED row. Price and availability only: only price changes (price, was price, RRP, saving, special and clearance flags) and availability changes (in stock, listing status, deliverable, collectable, and each size or colour variant being added, removed or changing its listing status) return an UPDATED row; changes to descriptions, images, categories or other details never do. Selling price and availability only: like Price and availability only, but a price change counts only when the selling price (price) moves; was price, RRP, savings and promotion flags never return a row on their own. In every option, a home delivery availability change at your delivery postcode (for the product or one of its sizes or colours) returns an UPDATED row when Verify home delivery is on. Changing this option or Fetch reviews on a search with no State key continues from that search's saved state instead of starting over.

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

Off by default. When on, UPDATED rows (and EXPIRED rows) are short: article id, url, name, brand, seller type, current price and stock, previousPrice, plus priceChanges (old and new value of each moved price or availability field) and variantChanges (each size or colour variant added, removed or changed, with old and new values). With Verify home delivery on, the row also carries the delivery answer and deliveryChanges / variantDeliveryChanges. NEW rows always carry the complete product record. Review text is not fetched for compact rows.

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

Only used with Emit expired products. A product is marked EXPIRED only after it has been missing from this many complete scans in a row (default 1). Raise it (for example 3) so a product that briefly drops out of a search is not reported as gone. A product that comes back resets the count. A product URL whose lookup could not be read never counts as missing.

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

Optional. Pick the dataset of an earlier 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 set 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 BIG W Marketplace Scraper (named bigw-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 set 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.

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

Optional. Field names that must not count as a change, so a product is not returned as UPDATED just because of them. Use a top-level name (for example `rating`) or a dotted path for a nested field (for example `fulfilment.eta`; inside lists the path applies to every element). The fields are still returned in the output - they are only left out of change detection and `changedFields`. Changing this list never re-reports products already tracked. Incremental mode only.

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

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write/digest. Leave empty to skip; never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

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

URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

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

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

## Actor input object example

```json
{
  "mode": "search",
  "queries": [
    "piano keyboard"
  ],
  "urls": [
    "https://www.bigw.com.au/search?text=piano",
    "https://www.bigw.com.au/search?text=piano&page=2",
    "https://m.bigw.com.au/search?text=lego",
    "https://www.bigw.com.au/product/x/p/9900004603",
    "https://www.bigw.com.au/toys/lego/c/6822101"
  ],
  "marketplaceOnly": true,
  "soldBy": "",
  "fulfilment": "",
  "specialsCategory": "",
  "sortBy": "relevance",
  "includeOutOfStock": true,
  "fetchReviews": false,
  "maxReviewsPerProduct": 20,
  "maxItems": 20,
  "maxPages": 0,
  "verifyHomeDelivery": false,
  "proxy": {
    "useApifyProxy": true
  },
  "allowBackupConnection": true,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "changeScope": "all",
  "compactUpdates": false,
  "expireAfterMissedScans": 1,
  "maxNotifyListings": 50
}
```

# Actor output Schema

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

No description

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

No description

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

No description

## `delivery` (type: `string`):

No description

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

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "search",
    "queries": [
        "piano keyboard"
    ],
    "urls": [
        "https://www.bigw.com.au/search?text=piano",
        "https://www.bigw.com.au/search?text=piano&page=2",
        "https://m.bigw.com.au/search?text=lego",
        "https://www.bigw.com.au/product/x/p/9900004603",
        "https://www.bigw.com.au/toys/lego/c/6822101"
    ],
    "proxy": {
        "useApifyProxy": true
    },
    "changeScope": "all",
    "compactUpdates": false,
    "expireAfterMissedScans": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/bigw-marketplace-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",
    "queries": ["piano keyboard"],
    "urls": [
        "https://www.bigw.com.au/search?text=piano",
        "https://www.bigw.com.au/search?text=piano&page=2",
        "https://m.bigw.com.au/search?text=lego",
        "https://www.bigw.com.au/product/x/p/9900004603",
        "https://www.bigw.com.au/toys/lego/c/6822101",
    ],
    "proxy": { "useApifyProxy": True },
    "changeScope": "all",
    "compactUpdates": False,
    "expireAfterMissedScans": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/bigw-marketplace-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",
  "queries": [
    "piano keyboard"
  ],
  "urls": [
    "https://www.bigw.com.au/search?text=piano",
    "https://www.bigw.com.au/search?text=piano&page=2",
    "https://m.bigw.com.au/search?text=lego",
    "https://www.bigw.com.au/product/x/p/9900004603",
    "https://www.bigw.com.au/toys/lego/c/6822101"
  ],
  "proxy": {
    "useApifyProxy": true
  },
  "changeScope": "all",
  "compactUpdates": false,
  "expireAfterMissedScans": 1
}' |
apify call abotapi/bigw-marketplace-scraper-lite --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/bigw-marketplace-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/lF558EIhKrwGvEz5d/builds/p88YozJcLG1pX04sF/openapi.json
