# Next.co.uk Scraper - Products, Prices, Sizes & Stock (`abotapi/next-uk-product-scraper`) Actor

Scrape Next.co.uk: keyword search, category and product-listing walks, full product details (price, was-price, sizes, stock, composition, images). Monitoring (NEW, UPDATED), incremental runs, resume.

- **URL**: https://apify.com/abotapi/next-uk-product-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Features:** Limited permissions
- **Stats:** 5 total users, 1 monthly users, 63.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 product records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Next.co.uk Scraper: Products, Prices, Sizes and Stock

Next.co.uk Scraper turns Next.co.uk, one of the UK's largest fashion and homeware retailers, into structured product data. Search by keyword, or paste any mix of category links, product listing links, style page links and bare product IDs, and get back title, current price and (when reduced) the previous price, size availability, stock markers, fabric composition and every product image. Turn on incremental mode for scheduled monitoring, or call the actor from your own code and read results straight from the dataset or the API.

### Why This Scraper?

- **Two ways to find products.** Use the site's own keyword search, or paste category links, listing links, style page links and bare product IDs (for example `Y00003`) into one list.
- **Full detail on demand.** Open every collected product for its detail page to get sizes, stock, composition and the full image set, or turn that off for faster, cheaper listing rows only.
- **Filter and sort before paying for detail.** Price range and reduced-only filtering, and a choice of sort order, apply to listing cards before any detail page opens, so filtered-out products never carry the detail surcharge.
- **Site facets without extra API knowledge.** For filters the site itself does not expose as search parameters, such as size, colour or brand, paste a filtered listing link straight into the links list.
- **Built for schedules.** Incremental mode returns only new and updated products on repeat runs of the same search or listing.
- **Fails loudly, not silently.** A run where every request was refused stops with a clear message instead of shipping an empty dataset.

### Use Cases

- **Retail price monitoring:** track price, was-price and stock changes across a category or a saved list of products over time.
- **Deal and markdown tracking:** filter for reduced-only products to catch new promotions as they appear.
- **Catalog and merchandising research:** pull a full category or search result to study range breadth, sizing and composition.
- **Product data enrichment:** resolve a list of product IDs or style links into full detail (sizes, stock, composition, images) for a downstream catalog or feed.
- **Fashion and trend analysis:** collect search results across many keywords to study naming, colours and price bands.

### Data You Get

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

| Field | Example |
| --- | --- |
| `kind` | `"product"` |
| `id` | `"Y00001"` |
| `title` | `"Sample Print Midi Dress"` |
| `url` | `"https://www.next.co.uk/style/-/y00001"` |
| `price` | `45.0` |
| `currency` | `"GBP"` |
| `wasPrice` | `65.0` (`null` unless the product is currently reduced) |
| `priceMin` / `priceMax` | `39.0` / `49.0` (detail rows only; `null` unless the product is sold across a price range) |
| `sizes` | `["8", "10", "12", "14"]` (from the detail page) |
| `outOfStockMarkers` | `2` (how many sizes of this colourway are shown as out of stock; a raw count, not a per-size map) |
| `lowStock` | `true` (at least one size is shown as low in stock) |
| `images` | list of product image URLs (the main shots plus the product gallery, up to 12) |
| `image` | `"https://xcdn.next.co.uk/sample/Y00001.jpg"` (one convenience image; can be `null`, and not included on rows from style links or product IDs you paste directly) |
| `composition` | `"100% Polyester"` (from the detail page) |
| `rating` / `reviewCount` | `4.6` / `12` (detail rows only; average star rating and total reviews on the site, `null` when unrated) |
| `reviews` | list of up to `maxReviewsPerProduct` reviews, each with `id`, `reviewer`, `rating`, `date`, `title`, `text`, `helpfulVotes`, `unhelpfulVotes`, `recommended`, `verifiedPurchase` and `replies` (store responses) |
| `itemNumber` / `rank` / `searchTerm` | `"Y00001"` / `3` / `"dresses"` (the style code; `rank` is the product's position in the site's own order within one listing link, counted from the first page the run loaded for that link and restarting for every link, so products removed by your price or sale filters leave gaps and a pasted `?p=2` link starts at 1; the search keyword from the link or query, `null` for direct style links and IDs) |
| `brand` / `colour` / `department` / `productCategory` / `fit` | `"Next"` / `"Blue Check"` / `"Womenswear"` / `"Dresses"` / `"Regular"` (brand, colour, department and fit also appear on listing-only rows; the category comes from the detail page) |
| `availableFits` / `colourwaysCount` | `["Regular"]` / `4` (detail page fits; number of colourways shown on the listing) |
| `minPrice` / `maxPrice` | `39.0` / `49.0` (same as `priceMin` / `priceMax`, falling back to `price` when the product has no range) |
| `newIn` / `territory` / `language` / `realm` / `criteriaUrl` | `true` / `"GB"` / `"en"` / `"next"` / the listing link the row came from (`newIn` is `true` when you walk a New In listing link; otherwise it is `null`, meaning unknown, because ordinary listings and style pages carry no new-in marker) |
| `detailFetched` | `true` when the detail page was opened successfully; `false` when it was requested but refused; not included on listing-only rows |
| `changeType` | `"NEW"`, `"UPDATED"` or `"UNCHANGED"` (incremental mode only) |
| `changedFields` | `["price", "sizes"]` (incremental mode only, present on `UPDATED` rows; names the tracked fields that changed) |
| `firstSeenAt` / `lastSeenAt` | `"2026-09-01T09:00:00+00:00"` / `"2026-09-29T09:00:00+00:00"` (incremental mode only, on `UPDATED` and `UNCHANGED` rows; not on `NEW` rows) |

Listing-only rows (when full detail is off) carry `kind`, `id`, `title`, `url`, `price`, `currency`, `wasPrice` and `image` only (no `detailFetched` key); the sizes, stock, composition and full image fields are only filled in once a product's detail page has been opened.

**Dataset views:** The dataset has four views: **Products** (listing columns), **Product detail** (sizes, stock, composition, images, rating), **Changes (incremental)** (change type and changed fields) and **Reviews** (one row per review, expanded from the `reviews` list).

### How to Use

1. Pick a **mode**: `search` (the site's own keyword search) or `links` (paste category links, listing links, style page links and bare product IDs, in any mix).
2. For search, fill in a query (plain keywords such as `school trousers` work). An untouched links field now scrapes one example of each supported shape. Pasted `?p=N` links start at that page (the site's page is 24 products). Category links in either of the site's forms (`/shop/womens/clothing/dresses/f/colour-black` or `/shop/gender-women-category-dresses-colour-black`), their sort segments, brand links (`/brands/...`) and searches with the site's own filter parameters are read as given; an empty result means the site lists nothing for that link; unrecognized entries are skipped with a warning. For links, paste your list. Optionally set a **price range**, **Reduced only**, and a **sort order**; these apply to search results and walked listing pages before any detail page opens (style links and product IDs you paste directly are always returned).
3. Turn **Open each product for full detail** on for sizes, stock, composition and images, or off for faster, listing-row-only output. Set **Max items** to control run size and cost.
4. Click **Start**, then download the dataset as JSON, CSV or Excel, or read it through the API.

**Keyword search:**

```json
{
  "mode": "search",
  "searchQuery": "midi dresses",
  "maxItems": 30
}
```

**Paste a mix of links, style pages and product IDs:**

```json
{
  "mode": "links",
  "links": [
    "https://www.next.co.uk/shop/gender-women-category-dresses",
    "https://www.next.co.uk/style/sv100000/y00001",
    "Y00002"
  ],
  "fetchDetails": true
}
```

**Filtered, sorted, listing rows only (no detail surcharge):**

```json
{
  "mode": "search",
  "searchQuery": "school trousers",
  "sortBy": "price-asc",
  "maxPrice": 30,
  "fetchDetails": false
}
```

**Daily monitoring of a category:**

```json
{
  "mode": "links",
  "links": ["https://www.next.co.uk/shop/gender-women-category-dresses"],
  "incrementalMode": true,
  "maxItems": 0
}
```

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/next-uk-product-scraper").call(
    run_input={"mode": "search", "searchQuery": "midi dresses", "maxItems": 30})
for product in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(product["title"], product["price"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/next-uk-product-scraper').call({
  mode: 'search', searchQuery: 'midi dresses', maxItems: 30,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

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

#### How Max items and sorting interact

Site relevance order streams results and pushes each product as soon as it is resolved. Price low to high and price high to low are ordered by the site itself across the whole result set for searches and for `/shop/gender-...` style category links, so the run reads only as many results as **Max items** needs (within one link; with several links, each link contributes its own first **Max items** and the combined list is sorted again). Title A to Z, and any sort on a `/shop/womens/...` style category link, needs the whole result set first: the actor reads listing pages, buffers up to 2000 matching products, sorts them, and returns the first **Max items**, so it starts a little slower, and a search or category with more than 2000 matching products is sorted over its first 2000 only. Links that can only be read from the site's own pages (see below) always use the buffered sort.

#### Resume and recurring updates

- **Resume** (`resumeFromRunId`) is accepted, but in the current build it does not skip anything: the previous run's product IDs are loaded, but they are never matched against the new run's products, so a resumed run starts from the first listing page again and returns, and bills, every product it reaches, including ones already collected. Example: a first run with Max items 3 returns products A, B and C; resuming from it with Max items 3 returns A, B and C again, not the next three. Workaround: do not rely on Resume to continue a pull. Rerun with a higher **Max items** (or `0`) instead, and de-duplicate on `id` downstream if you combine datasets.
- **Incremental mode** (`incrementalMode`) is for repeat runs over the same search or listing, for example a daily schedule. The first run returns every matching product as `NEW`; later runs return `NEW` and `UPDATED` only (price, sizes or stock changed since last time), and unchanged rows are suppressed and not billed unless **Emit unchanged records** is on. `stateKey` names the saved state, or leave it blank to derive one from the rest of your run settings. `changedFields` on an `UPDATED` row names the fields that changed (title, price, wasPrice, sizes, outOfStockMarkers, composition). **Ignore fields when detecting changes** (`ignoreFieldsForChanges`) lists fields that must not count as a change; they stay in the output. Changing that list never re-bills your saved products. If a product's detail page is refused on one run, its row lacks sizes, stock and composition, so it can be reported (and billed) as `UPDATED` on that run and again on the next successful one. `outOfStockMarkers` now counts the sizes that are really sold out (earlier builds reported a fixed 0 or 1); on the first run after this change, a saved product whose only difference is that corrected count is updated in the saved state silently (not returned, not billed), so your saved state picks up the real count without a wave of `UPDATED` rows; with **Emit unchanged records** off you see the corrected count the next time that product changes. Because it is now a real per-size count, `outOfStockMarkers` changes more often than before (each time a size sells out or comes back), and each such change returns an `UPDATED` row; if you do not want those updates, add `outOfStockMarkers` to **Ignore fields when detecting changes** (`ignoreFieldsForChanges`).

  **Known limitation:** on any one listing page (or, with a non-default sort, across the whole buffered result), **Max items** is applied to products in store order before they are checked against the saved state. If the first products in that order turn out to be unchanged, the run can stop there without ever reaching a genuinely new or updated product ranked lower on the same page, even though the page held more products. Example: a page holds 10 products, Max items is 5, and the first 5 happen to be unchanged from last run while the 6th is brand new; that run returns nothing from the page, never opens the new product, and keeps missing it on later runs as long as those products keep the same order. The same happens with a non-default sort across the whole buffered result: with **Sort results by** set to price low to high and Max items 5, if the 5 cheapest products are unchanged and a new product is the 6th cheapest, the run returns nothing. Such a run ends with no rows rather than failing. Workaround: set **Max items** to `0` (no limit) for incremental or monitoring runs, or set it well above one page's worth of products.

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

Optionally pipe results into the apps you already use through 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 (a title plus its key fields as 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 **`mcpConnectors`** field. (If the picker is empty, you have not authorized a connector yet.)
3. For **Notion**, also set `notionParentPageUrl` to the page where items should be created.

The connection goes through 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` (the site's own keyword search) or `links` (paste category, listing, style page or product ID entries). |
| `searchQuery` | string | (none) | Search mode: keyword or phrase, for example `dresses` or `school trousers`. |
| `links` | array | one example per shape (keyword search, paginated search, category, paginated category, sorted category, style page). Placeholder style links and bare product IDs are accepted but not sampled, as they resolve to the same product as the style example | Links mode: category/listing links are walked with pagination; style page links and bare product IDs return full detail. |
| `sortBy` | string | `relevance` | `relevance`, `price-asc`, `price-desc`, or `title-asc`. Applies in both modes before detail pages open. |
| `minPrice` | integer | (none) | Return only products priced at or above this (GBP). Products without a visible price are skipped when a price filter is set. |
| `maxPrice` | integer | (none) | Return only products priced at or below this (GBP). Blank means no maximum. |
| `onSaleOnly` | boolean | `false` | Return only products currently showing a was-price. |
| `fetchDetails` | boolean | `true` | Open every collected product's detail page for sizes, stock, composition and images. Off returns listing rows only. |
| `maxReviewsPerProduct` | integer | `20` | Customer reviews collected per product that is opened for detail, newest first (`0` = off, maximum `500` to keep runs bounded). Reviews are included in the product's normal rows and add no separate charge. |
| `maxItems` | integer | `20` | Stop after this many records (`0` = no limit; the run then stops when listings run out). |
| `maxPages` | integer | `0` | Stop walking each listing or search after this many pages (`0` = the built-in limit of 500 pages per link). |
| `results_wanted` | integer | (none) | Alias of `maxItems` for users migrating from other scrapers; when set it overrides `maxItems`. |
| `resumeFromRunId` | string | (none) | Paste a previous run or dataset ID to continue a large pull. See the Resume limitation above. |
| `incrementalMode` | boolean | `false` | Turn on for scheduled monitoring runs: later runs return only new and updated products. |
| `stateKey` | string | (none) | Optional name for an incremental-mode state. Leave blank to derive one from the rest of the run settings. |
| `emitUnchanged` | boolean | `false` | Incremental mode only: also return (and bill) products that have not changed since the last run. |
| `ignoreFieldsForChanges` | array | `[]` | Incremental mode only: field names that never count as a change. |
| `mcpConnectors` | array | no default | Optional MCP connectors to export results into (Notion, Linear, Airtable, Apify). |
| `notionParentPageUrl` | string | no default | Notion connector only: page under which item pages are created. |
| `maxNotifyListings` | integer | `50` | Cap on items exported to each connector per run. Does not affect the dataset. |
| `proxyConfiguration` | object | Apify Proxy | Connection settings. The site's edge refuses ordinary connections in waves on its listing routes; the actor automatically falls back to a backup connection for those pages unless you bring your own proxy. |

### Output Example

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

```json
{
  "kind": "product",
  "id": "Y00001",
  "title": "Sample Print Midi Dress",
  "url": "https://www.next.co.uk/style/-/y00001",
  "price": 45.0,
  "currency": "GBP",
  "wasPrice": 65.0,
  "priceMin": null,
  "priceMax": null,
  "sizes": ["8", "10", "12", "14"],
  "outOfStockMarkers": 2,
  "lowStock": true,
  "images": [
    "https://xcdn.next.co.uk/sample/Y00001_1.jpg",
    "https://xcdn.next.co.uk/sample/Y00001_2.jpg"
  ],
  "image": "https://xcdn.next.co.uk/sample/Y00001_1.jpg",
  "composition": "100% Polyester",
  "detailFetched": true,
  "changeType": "UPDATED",
  "changedFields": ["record"],
  "firstSeenAt": "2026-09-01T09:00:00+00:00",
  "lastSeenAt": "2026-09-29T09:00:00+00:00"
}
```

### Plan Requirement

Product data is read first from the site's own catalogue services, which answer on the default connection: searches, category and brand links in every form, style links and product IDs all come from there. Only a link or product those services cannot serve at that moment falls back to the site's pages.

Next.co.uk's edge refuses ordinary datacenter and residential proxy connections on its pages, so there is no setting that works by itself on those. For the page fallback the actor handles this automatically: when the default connection is refused it switches to a backup connection and reads the pages from there. This needs an Apify plan that includes proxy access. Pages can take tens of seconds each over the backup connection, and it opens and closes in waves, so a run may be slower than usual or skip some pages; the run's status message reports how many were refused.

On a plan where the default connection is unavailable but the backup connection can be opened, you will see this warning in the log:

> 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.

and, once the backup connection serves pages, `Served over the backup connection (the default connection was unavailable).` If no page can be read at all, the run fails with one of these messages:

- `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.`
- `No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Next pages.`
- `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.`

If you bring your own proxy with `proxyUrls`, runs are never re-routed to the backup connection.

When neither connection can be opened (a plan with no proxy access at all) the warning above is not shown and the run fails straight away with the first message.

### FAQ

#### How much does it cost?

You pay per product record returned (the dataset item event), once per product opened for full detail (the detail enrichment event, which also covers that product's reviews), and a start event per run. The **Pricing** tab shows the current rates. Use **Max items** to cap the cost of any run.

#### Is it legal to scrape Next.co.uk?

This actor collects only publicly available product data. You are responsible for how you use it: follow Next.co.uk's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product prices and availability change constantly and are only accurate as of the run that collected them.

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

Yes. Schedule the actor from the **Schedules** tab and turn on **Incremental changes for scheduled runs**. Each run then returns only new and updated products, and unchanged ones are not returned or billed unless you turn on **Emit unchanged records**.

#### Why did my scheduled run miss a product I know changed?

See the known limitation under Resume and recurring updates above. With incremental mode on, **Max items** is applied in store order (or, with a non-default sort, in sorted order) before products are compared with the last run. If the first products are unchanged, they use up the cap and a genuinely new or updated product ranked lower is never checked. Example: Max items 5, a page of 10 products, the first 5 unchanged and the 6th new: the run returns nothing. Set **Max items** to `0`, or well above one page's worth of products, for monitoring runs.

#### Why did a resumed run return products I already have?

In the current build, Resume does not filter out products from the previous run, so a resumed run starts over and returns (and bills) the same products again. Rerun with a higher **Max items** instead, and de-duplicate on `id` downstream if you combine datasets.

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

If the site refuses every single request in a run, the run stops with a clear message so "no matching products" is never confused with "nothing could be read." Run it again in a few minutes, or with fewer items. If only some pages were refused, you still get what was found, and the run's status message reports how many were refused.

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

Yes. Call it from any Apify integration or MCP client like any other actor, and read the results from the dataset or the API.

### 🔗 Want more fashion data?

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

<table>
<tr><td>👗 <a href="https://apify.com/abotapi/24s-com-scraper"><b>24S Scraper</b></a><br>Scrape 24S luxury fashion by category, filters, or URL. Extract brand, name, price...</td><td>👗 <a href="https://apify.com/abotapi/nuuly-com-scraper"><b>Nuuly Scraper</b></a><br>Scrape Nuuly clothing rental products by category, brand or URL. Extract product names...</td></tr>
<tr><td>👗 <a href="https://apify.com/abotapi/mango-com-scraper"><b>Mango Scraper</b></a><br>Scrape Mango (shop.mango.com) fashion products: current price plus strike-through Rebajas...</td><td>👗 <a href="https://apify.com/abotapi/fashionnova-com-scraper"><b>Fashion Nova Scraper</b></a><br>Scrape Fashion Nova products by keyword, collection or URL. Extract product names...</td></tr>
<tr><td>👗 <a href="https://apify.com/abotapi/zozotown-scraper"><b>ZOZOTOWN</b></a><br>Scrape ZOZOTOWN (zozo.jp), Japan's largest fashion marketplace: name, brand, JPY price...</td><td>👗 <a href="https://apify.com/abotapi/renttherunway-scraper"><b>Rent the Runway Scraper</b></a><br>Scrape Rent the Runway (renttherunway.com) designer clothing and accessories by category...</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/next-uk-product-scraper/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 runs the site's keyword search with pagination. Links reads any next.co.uk links you paste: category and product-listing pages are walked with pagination; style pages and bare product IDs return full product detail.

## `searchQuery` (type: `string`):

Search mode: keyword or phrase (e.g. dresses, school trousers, women's coats).

## `links` (type: `array`):

Links mode: category/product-listing links are walked with pagination; /style/... links and bare product IDs (e.g. Y76826) return full product detail. Left untouched, the field scrapes one example of each supported shape (keyword search, category, paginated and sorted listings, a style page). Placeholder style links (/style/-/<id>) and bare product IDs such as Y76826 are also accepted but are not in the sample list, because they resolve to the same product as the style example.

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

Applies in both Search and Links modes. Site relevance keeps the site's own order and streams results as they come; any other value reads listing pages first, sorts, then returns the first Max items, so the run starts slower.

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

Return only products priced at or above this. Products without a visible price are skipped when a price filter is set.

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

Return only products priced at or below this. Blank means no maximum.

## `onSaleOnly` (type: `boolean`):

Return only products showing a was-price (currently reduced).

## `fetchDetails` (type: `boolean`):

Open every collected product for its detail page (sizes, stock, composition, all images). Off returns listing-card rows only, faster and cheaper.

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

Customer reviews to collect for each product that is opened for detail (newest first). 0 turns reviews off. Requires detail fetch. Capped at 500 to keep runs bounded.

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

Stop after this many records (0 = no limit; the run then stops when listings run out).

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

Stop walking each listing or search after this many pages (0 = the built-in limit of 500 pages per link; Max items still applies). Each page holds up to about 100 products.

## `results_wanted` (type: `integer`):

Alias of Max items for users migrating from other scrapers. When set, it overrides Max items.

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

Apify Proxy settings. The site's edge refuses ordinary connections in waves on its listing routes; the actor automatically uses its backup connection for those pages when needed. Bring your own proxy with proxyUrls if you prefer.

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

Paste a previous run ID or dataset ID to continue a large pull without returning items already collected there.

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

Turn this on for daily or recurring monitoring. The first run returns every matching product as NEW. Later runs normally return only NEW and UPDATED products (price, sizes or stock changed). Turn on Emit unchanged only when you also want those rows returned (and billed).

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

Optional. Name this monitoring campaign to keep its state stable. Leave empty to derive a key from the run settings.

## `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.

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

Field names that must not count as a change in incremental mode, for example `sizes` or `outOfStockMarkers`. A product whose only difference is in these fields stays UNCHANGED. Tracked fields: title, price, wasPrice, sizes, outOfStockMarkers, composition. Changing this list does not re-bill your saved products.

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

Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify -> Settings -> Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON; the complete record stays in the dataset. Leave empty to skip. 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",
  "searchQuery": "dresses",
  "links": [
    "https://www.next.co.uk/search?w=dresses",
    "https://www.next.co.uk/search?w=dresses&p=2",
    "https://www.next.co.uk/shop/gender-women-category-dresses",
    "https://www.next.co.uk/shop/gender-women-category-dresses?p=2",
    "https://www.next.co.uk/shop/gender-women-category-dresses/sort-priceasc",
    "https://www.next.co.uk/style/sv132147/y76826"
  ],
  "sortBy": "relevance",
  "onSaleOnly": false,
  "fetchDetails": true,
  "maxReviewsPerProduct": 20,
  "maxItems": 20,
  "maxPages": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}
```

# Actor output Schema

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

No description

## `detail` (type: `string`):

No description

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

No description

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

No description

## `runSummary` (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",
    "searchQuery": "dresses",
    "links": [
        "https://www.next.co.uk/search?w=dresses",
        "https://www.next.co.uk/search?w=dresses&p=2",
        "https://www.next.co.uk/shop/gender-women-category-dresses",
        "https://www.next.co.uk/shop/gender-women-category-dresses?p=2",
        "https://www.next.co.uk/shop/gender-women-category-dresses/sort-priceasc",
        "https://www.next.co.uk/style/sv132147/y76826"
    ],
    "sortBy": "relevance",
    "onSaleOnly": false,
    "fetchDetails": true,
    "maxReviewsPerProduct": 20,
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "ignoreFieldsForChanges": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/next-uk-product-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "search",
    "searchQuery": "dresses",
    "links": [
        "https://www.next.co.uk/search?w=dresses",
        "https://www.next.co.uk/search?w=dresses&p=2",
        "https://www.next.co.uk/shop/gender-women-category-dresses",
        "https://www.next.co.uk/shop/gender-women-category-dresses?p=2",
        "https://www.next.co.uk/shop/gender-women-category-dresses/sort-priceasc",
        "https://www.next.co.uk/style/sv132147/y76826",
    ],
    "sortBy": "relevance",
    "onSaleOnly": False,
    "fetchDetails": True,
    "maxReviewsPerProduct": 20,
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": True },
    "incrementalMode": False,
    "emitUnchanged": False,
    "ignoreFieldsForChanges": [],
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/next-uk-product-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "search",
  "searchQuery": "dresses",
  "links": [
    "https://www.next.co.uk/search?w=dresses",
    "https://www.next.co.uk/search?w=dresses&p=2",
    "https://www.next.co.uk/shop/gender-women-category-dresses",
    "https://www.next.co.uk/shop/gender-women-category-dresses?p=2",
    "https://www.next.co.uk/shop/gender-women-category-dresses/sort-priceasc",
    "https://www.next.co.uk/style/sv132147/y76826"
  ],
  "sortBy": "relevance",
  "onSaleOnly": false,
  "fetchDetails": true,
  "maxReviewsPerProduct": 20,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "ignoreFieldsForChanges": []
}' |
apify call abotapi/next-uk-product-scraper --silent --output-dataset

```

## MCP server setup

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

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/eFB7O2D3nKapU4W4U/builds/Ay1RdIbAPgwxkWO8M/openapi.json
