# dm.de - Prices, Offers, Unit Price & Reviews (`abotapi/dm-de-scraper`) Actor

Scrape dm-drogerie markt (dm.de) products: current + strike-through Ausverkauf price with discount, per-unit pricing (per 100ml/kg/piece), brand incl. dm own-brands, EAN, ingredients, pack-size variants, and full reviews with rating breakdown. Search or paste links.

- **URL**: https://apify.com/abotapi/dm-de-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 product results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## dm.de Product Scraper

Pull rich product data from dm-drogerie markt (dm.de), Germany's drugstore and personal-care retailer. Search by keyword, a real dm.de category, or the site's own currently-reduced Ausverkauf items, or paste product and listing links directly. Every record includes the current price, the strike-through original price with computed discount when a product is marked down, per-unit pricing (e.g. price per 100 ml or per kg) where the site shows it, and a complete customer review history with a full rating breakdown.

### Why This Scraper?

- **Was-price and discount, structured, not scraped from a badge.** When a product carries a reduced original price, both prices are captured plus the computed discount amount and percentage.
- **Real per-unit pricing.** Bodycare, food, and household products return their price per 100 ml / 100 g / kg / piece separately from the pack price, exactly as the site itself breaks it down.
- **Ausverkauf, first class.** A `specialsOnly` toggle narrows any search or category listing to dm's own live clearance/sellout feed -- the site's real, queryable discount signal, not a guessed category.
- **Full review history.** Overall rating, review count, a full 1 to 5 star rating breakdown, and every individual review with author, date, rating, title, and body text.
- **Rich detail on demand.** Full breadcrumb category path, flattened product information (description, ingredients/Inhaltsstoffe, usage notes -- varies per category, never hardcoded), pack-size variants with their own price and EAN, brand image, and online/store availability.
- **Brand coverage.** Every brand dm carries, including its own private-label lines (dmBio, Balea, alverde NATURKOSMETIK, and more) alongside national brands.
- **Two ways in.** Keyword or category search with real site filters (brand, rating, price range, Ausverkauf, sort), or paste any product/listing link and continue pagination automatically.
- **Optional export to your apps.** Send results into Notion, Linear, Airtable, or any Apify MCP connector alongside the dataset.

### Data You Get

| Field | Example value |
|---|---|
| productId / sku | `1234567` |
| ean | `4058172548821` |
| name | `Sample Bodylotion Aloe Vera` |
| brand | `Sample Brand` |
| category / categoryPath | `Bodylotion & Hautcreme`, `["Pflege & Parfum", "Körperpflege", "Bodylotion & Hautcreme"]` |
| url | `https://www.dm.de/p/d/1234567/sample-bodylotion-aloe-vera` |
| price / currency | `3.45`, `EUR` |
| originalPrice / discountAmount / discountPercent | `4.95`, `1.50`, `30.3` |
| isOnSpecial / promoLabel | `true`, `Ausverkauf` |
| unitPrice / unitPriceBasis / packSize | `0.86`, `100 ml`, `400 ml` |
| rating / reviewCount | `4.6`, `128` |
| onlineAvailable / onlineAvailabilityStatus / storeAvailabilityStatus | `true`, `Lieferbar`, `Im Markt vorrätig` |
| image / images | `["https://www.dm.de/sample/image.png"]` |
| description / ingredients | full text fields |
| productDetails | `{"Produktmerkmale": "...", "Verwendungshinweise": "..."}` (flattened per category) |
| variants | `[{"productId": "1234568", "ean": "4058172548838", "label": "600 ml", "isSelected": false}]` |
| isPharmacy | `false` |
| reviews.averageRating / reviews.totalReviewCount | `4.6`, `128` |
| reviews.ratingDistribution | `[{"rating": 5, "count": 90}, {"rating": 4, "count": 24}, ...]` |
| reviews.items[] | `[{"rating": 5, "title": "Sample title", "body": "Sample review text.", "author": "Sample User", "date": "2026-07-12T07:31:15.000Z", "isRecommended": true, "verifiedPurchaser": true}]` |

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

### How to Use

**1. Keyword search, first page, with reviews (default):**
```json
{
  "mode": "search",
  "searchTerm": "bodylotion",
  "maxItems": 20
}
````

**2. Category browse, filtered to a brand and only currently-reduced Ausverkauf items:**

```json
{
  "mode": "search",
  "searchTerm": "pflege-und-parfum/koerperpflege/bodylotion-und-hautcreme",
  "brands": ["Balea"],
  "specialsOnly": true,
  "sortBy": "PRICE_ASC",
  "maxItems": 50,
  "maxPages": 5
}
```

**3. Full product detail + reviews for pasted product links:**

```json
{
  "mode": "url",
  "urls": ["https://www.dm.de/p/d/1234567/sample-bodylotion-aloe-vera"],
  "fetchDetails": true,
  "fetchReviews": true,
  "maxReviewsPerProduct": 0
}
```

**4. Paste a listing link and keep paginating forward:**

```json
{
  "mode": "url",
  "urls": ["https://www.dm.de/search?query=bodylotion"],
  "maxItems": 100,
  "maxPages": 10
}
```

### Input Parameters

| Parameter | Type | Description |
|---|---|---|
| `mode` | string | `search` or `url`. |
| `searchTerm` | string | Keyword or a real dm.de category path (search mode only). |
| `specialsOnly` | boolean | Keep only products currently in dm's Ausverkauf/clearance feed (search mode only). |
| `brands` | array | Exact brand names to keep (search mode only). |
| `minRating` | integer | 1-5, minimum rating to keep (search mode only). |
| `minPrice` / `maxPrice` | number | EUR price band to keep (search mode only). |
| `sortBy` | string | `RELEVANCE`, `PRICE_ASC`, `PRICE_DESC`, `NEWEST`, or `RATING` (search mode only). |
| `urls` | array | Product or listing URLs to scrape (url mode only). |
| `fetchDetails` | boolean | Fetch full product detail (breadcrumb, description, ingredients, pack-size variants, brand image, availability). Pasted product URLs always fetch detail, and are charged for it, regardless of this toggle. |
| `fetchReviews` | boolean | Fetch full review history. Shares one enrichment charge with `fetchDetails`, applied at most once per product. |
| `maxReviewsPerProduct` | integer | Cap on reviews per product; `0` = all. |
| `maxPages` | integer | Cap on result pages per search/category/URL entry; empty = unlimited. |
| `maxItems` | integer | Cap on total products returned; `0` = unlimited. |
| `proxy` | object | Apify proxy configuration. Works on every plan by default. |
| `mcpConnectors` | array | Optional MCP connectors to export results into (Notion, Linear, Airtable, Apify). |
| `notionParentPageUrl` | string | Notion connector only: page under which item pages are created. |
| `maxNotifyListings` | integer | Cap on items exported to each connector per run. Does not affect the dataset. |

### Output Example

```json
{
  "productId": "1234567",
  "sku": "1234567",
  "ean": "4058172548821",
  "name": "Sample Bodylotion Aloe Vera",
  "brand": "Sample Brand",
  "category": "Bodylotion & Hautcreme",
  "url": "https://www.dm.de/p/d/1234567/sample-bodylotion-aloe-vera",
  "price": 3.45,
  "currency": "EUR",
  "originalPrice": 4.95,
  "discountAmount": 1.5,
  "discountPercent": 30.3,
  "isOnSpecial": true,
  "promoLabel": "Ausverkauf",
  "unitPrice": 0.86,
  "unitPriceBasis": "100 ml",
  "packSize": "400 ml",
  "rating": 4.6,
  "reviewCount": 128,
  "onlineAvailable": true,
  "image": "https://www.dm.de/sample/image.png",
  "reviews": {
    "averageRating": 4.6,
    "totalReviewCount": 128,
    "ratingDistribution": [{ "rating": 5, "count": 90 }, { "rating": 4, "count": 24 }],
    "items": [
      {
        "rating": 5,
        "title": "Sample title",
        "body": "Sample review text.",
        "author": "Sample User",
        "date": "2026-07-12T07:31:15.000Z",
        "isRecommended": true,
        "verifiedPurchaser": true
      }
    ]
  }
}
```

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

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

Optionally pipe results into the apps you already use through Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, Integrations, then select it in the `mcpConnectors` field. Each connector receives a condensed, human-readable summary per product (name plus key fields), while the complete record always stays in the Apify dataset. For Notion, set `notionParentPageUrl` to the page the item pages should be created under, and use `maxNotifyListings` to cap how many items are exported per connector per run. Supported connectors: Notion, Linear, Airtable, and Apify. Leave the field empty to skip; it never changes the dataset output.

### A note on plans

The default connection works on every Apify plan, including the free tier. A residential proxy connection is optional and only worth turning on for very large or sustained runs.

# Actor input Schema

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

'search' finds products by keyword, by a real dm.de category (e.g. 'haare' or 'pflege-und-parfum/koerperpflege/bodylotion-und-hautcreme'), and/or the site's own currently-reduced Ausverkauf items, with real site filters. 'url' scrapes any product or category/listing page URL you paste, walking pagination forward automatically.

## `searchTerm` (type: `string`):

Free-text keyword (e.g. 'shampoo') or a real dm.de category path exactly as it appears in the site's own navigation or URLs (e.g. 'haare' or 'pflege-und-parfum/koerperpflege/bodylotion-und-hautcreme'). Leave empty and enable Ausverkauf only below to browse the whole clearance feed.

## `specialsOnly` (type: `boolean`):

dm.de's real, queryable promo taxonomy is its 'Ausverkauf' (clearance/sellout) feed -- verified live. There is no separate queryable 'Angebote'/'Aktion' product feed: the site's 'Aktionen' nav entry is an editorial content hub with no product API behind it, so it is intentionally not exposed here. Turning this on narrows to Ausverkauf items (optionally combined with the keyword/category above), each carrying the site's own strike-through original price and discount.

## `brands` (type: `array`):

Only return products from these brands, e.g. 'Balea', 'dmBio', 'alverde NATURKOSMETIK', 'Nivea'. Match the exact brand name as shown on the site (includes dm's own private-label brands). Leave empty for all brands.

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

Only return products rated at or above this many stars, 1-5.

## `minPrice` (type: `number`):

Only return products priced at or above this amount, in euros.

## `maxPrice` (type: `number`):

Only return products priced at or below this amount, in euros.

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

dm.de's own sort order, verified live to reorder the full server-side result set (so it stays correct across pagination, not just within one fetched page).

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

Paste one or more dm.de product pages (.../p/d/<article number>/<slug>), or category/search listing pages (e.g. .../haare or .../search?query=shampoo). Pagination continues forward automatically from any ?currentPage= already in the URL. Filter fields above are ignored in this mode.

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

A pasted product link always fetches full detail regardless of this toggle, and is charged the enrichment surcharge either way — it has no listing card to fall back on, so without the detail fetch the record would be almost empty. Everywhere else, this toggle adds the full breadcrumb category path, category codes, description, ingredients (Inhaltsstoffe), all other product characteristics (flattened, varies per category), pack-size variants with their own price/EAN, brand image, and online/store availability from the product detail API. Current price, was-price/discount, unit price and rating are already included without this toggle. This toggle and 'Fetch reviews' share one enrichment surcharge, charged at most once per product.

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

Fetch each product's full review history: overall rating, review count, a full 1-5 rating breakdown, and per-review author/date/rating/title/body. Products with no reviews simply return an empty list. This toggle and 'Fetch full product detail' share one enrichment surcharge, charged at most once per product no matter how many reviews are fetched.

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

Cap on reviews fetched per product when 'Fetch reviews' is on. 0 = all available reviews.

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

Stop after this many result pages per search/category/URL entry. Leave empty for no page limit -- the run stops at Max products total.

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

Hard cap on total products returned across every search/category/URL entry. 0 = unlimited (still bounded by Max pages per search).

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

The default connection works on every Apify plan, including the free tier. A residential connection is optional and only needed for very large or sustained runs.

## `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",
  "searchTerm": "shampoo",
  "specialsOnly": false,
  "brands": [],
  "sortBy": "RELEVANCE",
  "urls": [
    "https://www.dm.de/search?query=shampoo"
  ],
  "fetchDetails": false,
  "fetchReviews": true,
  "maxReviewsPerProduct": 20,
  "maxItems": 20,
  "proxy": {
    "useApifyProxy": true
  },
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (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",
    "searchTerm": "shampoo",
    "brands": [],
    "urls": [
        "https://www.dm.de/search?query=shampoo"
    ],
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/dm-de-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",
    "searchTerm": "shampoo",
    "brands": [],
    "urls": ["https://www.dm.de/search?query=shampoo"],
    "proxy": { "useApifyProxy": True },
}

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

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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",
  "searchTerm": "shampoo",
  "brands": [],
  "urls": [
    "https://www.dm.de/search?query=shampoo"
  ],
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call abotapi/dm-de-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=abotapi/dm-de-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "dm.de - Prices, Offers, Unit Price & Reviews",
        "description": "Scrape dm-drogerie markt (dm.de) products: current + strike-through Ausverkauf price with discount, per-unit pricing (per 100ml/kg/piece), brand incl. dm own-brands, EAN, ingredients, pack-size variants, and full reviews with rating breakdown. Search or paste links.",
        "version": "1.0",
        "x-build-id": "2DK8mg7yYwWckPBQ9"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/abotapi~dm-de-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-abotapi-dm-de-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/abotapi~dm-de-scraper/runs": {
            "post": {
                "operationId": "runs-sync-abotapi-dm-de-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/abotapi~dm-de-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-abotapi-dm-de-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "search",
                            "url"
                        ],
                        "type": "string",
                        "description": "'search' finds products by keyword, by a real dm.de category (e.g. 'haare' or 'pflege-und-parfum/koerperpflege/bodylotion-und-hautcreme'), and/or the site's own currently-reduced Ausverkauf items, with real site filters. 'url' scrapes any product or category/listing page URL you paste, walking pagination forward automatically.",
                        "default": "search"
                    },
                    "searchTerm": {
                        "title": "Search keyword or category",
                        "type": "string",
                        "description": "Free-text keyword (e.g. 'shampoo') or a real dm.de category path exactly as it appears in the site's own navigation or URLs (e.g. 'haare' or 'pflege-und-parfum/koerperpflege/bodylotion-und-hautcreme'). Leave empty and enable Ausverkauf only below to browse the whole clearance feed."
                    },
                    "specialsOnly": {
                        "title": "Ausverkauf / clearance only",
                        "type": "boolean",
                        "description": "dm.de's real, queryable promo taxonomy is its 'Ausverkauf' (clearance/sellout) feed -- verified live. There is no separate queryable 'Angebote'/'Aktion' product feed: the site's 'Aktionen' nav entry is an editorial content hub with no product API behind it, so it is intentionally not exposed here. Turning this on narrows to Ausverkauf items (optionally combined with the keyword/category above), each carrying the site's own strike-through original price and discount.",
                        "default": false
                    },
                    "brands": {
                        "title": "Brands",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Only return products from these brands, e.g. 'Balea', 'dmBio', 'alverde NATURKOSMETIK', 'Nivea'. Match the exact brand name as shown on the site (includes dm's own private-label brands). Leave empty for all brands.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "minRating": {
                        "title": "Minimum rating",
                        "minimum": 1,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Only return products rated at or above this many stars, 1-5."
                    },
                    "minPrice": {
                        "title": "Minimum price (EUR)",
                        "type": "number",
                        "description": "Only return products priced at or above this amount, in euros."
                    },
                    "maxPrice": {
                        "title": "Maximum price (EUR)",
                        "type": "number",
                        "description": "Only return products priced at or below this amount, in euros."
                    },
                    "sortBy": {
                        "title": "Sort order",
                        "enum": [
                            "RELEVANCE",
                            "PRICE_ASC",
                            "PRICE_DESC",
                            "NEWEST",
                            "RATING"
                        ],
                        "type": "string",
                        "description": "dm.de's own sort order, verified live to reorder the full server-side result set (so it stays correct across pagination, not just within one fetched page).",
                        "default": "RELEVANCE"
                    },
                    "urls": {
                        "title": "URLs to scrape",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Paste one or more dm.de product pages (.../p/d/<article number>/<slug>), or category/search listing pages (e.g. .../haare or .../search?query=shampoo). Pagination continues forward automatically from any ?currentPage= already in the URL. Filter fields above are ignored in this mode.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "fetchDetails": {
                        "title": "Fetch full product detail",
                        "type": "boolean",
                        "description": "A pasted product link always fetches full detail regardless of this toggle, and is charged the enrichment surcharge either way — it has no listing card to fall back on, so without the detail fetch the record would be almost empty. Everywhere else, this toggle adds the full breadcrumb category path, category codes, description, ingredients (Inhaltsstoffe), all other product characteristics (flattened, varies per category), pack-size variants with their own price/EAN, brand image, and online/store availability from the product detail API. Current price, was-price/discount, unit price and rating are already included without this toggle. This toggle and 'Fetch reviews' share one enrichment surcharge, charged at most once per product.",
                        "default": false
                    },
                    "fetchReviews": {
                        "title": "Fetch reviews",
                        "type": "boolean",
                        "description": "Fetch each product's full review history: overall rating, review count, a full 1-5 rating breakdown, and per-review author/date/rating/title/body. Products with no reviews simply return an empty list. This toggle and 'Fetch full product detail' share one enrichment surcharge, charged at most once per product no matter how many reviews are fetched.",
                        "default": true
                    },
                    "maxReviewsPerProduct": {
                        "title": "Max reviews per product",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Cap on reviews fetched per product when 'Fetch reviews' is on. 0 = all available reviews.",
                        "default": 20
                    },
                    "maxPages": {
                        "title": "Max pages per search",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Stop after this many result pages per search/category/URL entry. Leave empty for no page limit -- the run stops at Max products total."
                    },
                    "maxItems": {
                        "title": "Max products total",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Hard cap on total products returned across every search/category/URL entry. 0 = unlimited (still bounded by Max pages per search).",
                        "default": 20
                    },
                    "proxy": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "The default connection works on every Apify plan, including the free tier. A residential connection is optional and only needed for very large or sustained runs.",
                        "default": {
                            "useApifyProxy": true
                        }
                    },
                    "mcpConnectors": {
                        "title": "Pipe results into your apps (optional)",
                        "type": "array",
                        "description": "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": {
                        "title": "Notion parent page (Notion connector only)",
                        "type": "string",
                        "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
                    },
                    "maxNotifyListings": {
                        "title": "Max items to export per connector",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Cap on items written to each connector per run. Does not affect the dataset.",
                        "default": 50
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
