# OTTO.de - Prices, Variants, Specs & Reviews (`abotapi/otto-de-scraper`) Actor

Extract rich product data from OTTO.de across fashion, furniture, electronics and homeware. Search or paste product and category URLs to get prices, discounts, colour and size variants, availability, brand, seller, EAN/GTIN, specifications, categories and customer reviews.

- **URL**: https://apify.com/abotapi/otto-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.20 / 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

## OTTO Product Scraper

Pull rich product data from OTTO.de, Germany's major general-retail marketplace: fashion, furniture (Möbel), technik, household appliances and more. Search by keyword or category, 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, the full colour/size variant matrix with per-variant availability, brand, seller identity, and native customer reviews.

### Why This Scraper?

- **Was-price and discount, structured, not scraped from a badge.** When a product carries a reduced price, both the current and original price are captured plus the computed discount percentage and the site's own promo label -- all from the listing fetch, zero extra cost.
- **Full colour/size variant matrix.** Every colour or size option a product offers is returned with its own variation id and availability, exactly as the site's own selector shows it.
- **Specials, first-class.** A `specialsOnly` toggle narrows any search to only products currently showing a reduced price, and `sortBy: DISCOUNT` surfaces the biggest reductions first -- both drive the site's own live discount signal, not a guessed category.
- **Seller transparency.** OTTO is a marketplace: every product's seller is captured, distinguishing OTTO itself from third-party marketplace partners, with the partner's own identifier.
- **Native review history.** Overall rating, review count, and every individual review with author, location, date, star rating, verified-purchase flag, body text, and helpful-vote counts -- sourced directly from the site, not a third-party review widget.
- **Rich detail on demand.** Full breadcrumb category path, flattened technical specifications (varies per product category, never hardcoded), EAN/GTIN/SKU, full image gallery, and return policy.
- **Two ways in.** Keyword or category search with real site filters (brand, rating, price range, specials, sort), or paste any product/listing link and continue pagination automatically.
- **Full-catalogue walk.** `maxPages` is 0 (unlimited) by default -- the run walks every result page for a search/category/URL entry until the site's own last page, `maxItems`, or a run out of new products. Set `maxPages` to a positive number only if you want to cap it.
- **Resume a previous run.** Paste a prior run or dataset id into `resumeFromRunId` to continue it: already-collected products are skipped, so the run returns only new products (a delta) instead of a full re-scrape.
- **Survives interruption.** Long unlimited-page runs checkpoint their progress; if the run is interrupted by an Apify platform migration or resumed via the Resurrect button, it picks up where it left off with no duplicate products and no double charges.
- **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 / variationId / articleNumber | `S0AB12CD`, `S0AB12CD4XYZ`, `S0AB12CDKIE` |
| name | `Sample Brand Ecksofa, Sofa L-Form, mit Schlaffunktion` |
| brand | `Sample Brand` |
| category / breadcrumb | `Ecksofas`, `[{"name": "Möbel", "url": "..."}, {"name": "Sofas", "url": "..."}, {"name": "Ecksofas", "url": "..."}]` |
| url | `https://www.otto.de/p/sample-ecksofa-S0AB12CD/` |
| price / currency | `799.00`, `EUR` |
| originalPrice / discountPercent / promoLabel | `1599.00`, `50`, `-50%` |
| isOnSpecial | `true` |
| availability / availabilityText | `AVAILABLE`, `lieferbar in 5 Wochen` |
| rating / reviewCount | `4.5`, `26` |
| variants[] | `[{"variationId": "S0AB12CD4XYZ", "color": "Khaki", "hexCode": "BEB2A9", "selected": true}, {"variationId": "S0AB12CD55VQ", "color": "Gold", "hexCode": "BEB2A8", "selected": false}]` |
| image / images | `["https://sample.example/img1.jpg", "https://sample.example/img2.jpg"]` |
| ean / gtin / sku | `4068181820000`, `4068181820000`, `S0AB12CD4XYZ` |
| specs | `{"Höhe": "85 cm", "Breite": "289 cm", "Polsterung": "Schaumstoff", "Design": "Modern"}` (flattened, varies per category) |
| seller | `{"name": "Sample Home Brands GmbH", "partnerId": "1000000", "sellerType": "MARKETPLACE_PARTNER"}` |
| returnPolicy | `{"days": 30, "freeReturn": true}` |
| reviews.averageRating / reviews.reviewCount | `4.5`, `26` |
| reviews.items[] | `[{"reviewId": "sample-uuid", "author": "Sample R.", "location": "Sample City", "date": "11.04.2026", "rating": 5, "verifiedPurchase": true, "title": null, "body": "Sample review text.", "helpfulVotes": 5, "helpfulVotesTotal": 5, "variantPurchased": "Farbe: Khaki", "seller": "Sample Home Brands GmbH"}]` |

> 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": "ecksofa",
  "maxItems": 20
}
````

**2. Category-style search, filtered to specials and sorted by biggest discount:**

```json
{
  "mode": "search",
  "searchTerm": "sofas",
  "specialsOnly": true,
  "sortBy": "DISCOUNT",
  "maxItems": 50,
  "maxPages": 5
}
```

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

```json
{
  "mode": "url",
  "urls": ["https://www.otto.de/p/sample-ecksofa-S0AB12CD/"],
  "fetchDetails": true,
  "fetchReviews": true,
  "maxReviewsPerProduct": 0
}
```

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

```json
{
  "mode": "url",
  "urls": ["https://www.otto.de/suche/ecksofa/"],
  "maxItems": 100,
  "maxPages": 10
}
```

### Input Parameters

| Parameter | Type | Description |
|---|---|---|
| `mode` | string | `search` or `url`. |
| `searchTerm` | string | Keyword or category name (search mode only). |
| `specialsOnly` | boolean | Keep only currently-discounted products (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`, `DISCOUNT`, `NEWEST`, or `RATING` (search mode only). |
| `urls` | array | Product or listing URLs to scrape (url mode only). |
| `fetchDetails` | boolean | Fetch full product detail (breadcrumb, specs, seller, EAN/GTIN/SKU, return policy). A pasted product URL always fetches its detail page regardless of this toggle, since that is the only source of its data. |
| `fetchReviews` | boolean | Fetch native customer reviews. |
| `maxReviewsPerProduct` | integer | Cap on reviews per product; `0` = all the product page renders. |
| `maxPages` | integer | Cap on result-page fetches per search/URL entry; `0` (default) = unlimited, walks the full catalogue until the site's own last page or Max products total. |
| `maxItems` | integer | Cap on total products returned; `0` = unlimited. |
| `resumeFromRunId` | string | Paste a previous run id (or its dataset id) to continue that run: products already collected there are skipped, so this run only returns new products (a delta). Leave empty for a normal run. |
| `proxy` | object | Apify proxy configuration for the listing route. Product detail/reviews always use residential regardless of this setting. |
| `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": "S0AB12CD",
  "variationId": "S0AB12CD4XYZ",
  "articleNumber": "S0AB12CDKIE",
  "name": "Sample Brand Ecksofa, Sofa L-Form, mit Schlaffunktion",
  "brand": "Sample Brand",
  "category": "Ecksofas",
  "url": "https://www.otto.de/p/sample-ecksofa-S0AB12CD/",
  "price": 799.00,
  "currency": "EUR",
  "originalPrice": 1599.00,
  "discountPercent": 50,
  "isOnSpecial": true,
  "availability": "AVAILABLE",
  "rating": 4.5,
  "reviewCount": 26,
  "variants": [
    { "variationId": "S0AB12CD4XYZ", "color": "Khaki", "hexCode": "BEB2A9", "selected": true }
  ],
  "image": "https://sample.example/img1.jpg",
  "reviews": {
    "averageRating": 4.5,
    "reviewCount": 26,
    "items": [
      {
        "reviewId": "sample-uuid",
        "author": "Sample R.",
        "location": "Sample City",
        "date": "11.04.2026",
        "rating": 5,
        "verifiedPurchase": true,
        "body": "Sample review text.",
        "helpfulVotes": 5,
        "helpfulVotesTotal": 5,
        "variantPurchased": "Farbe: Khaki",
        "seller": "Sample Home Brands GmbH"
      }
    ]
  }
}
```

> 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 (title 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 `proxy` field governs the product listing/search connection, which works on every Apify plan including the free tier. Product detail and reviews (on by default) always use a residential connection at extra cost, regardless of this setting.

# Actor input Schema

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

'search' finds products by keyword or category name, with real site filters and sort. 'url' scrapes any product, search-result, or category page URL you paste, walking pagination forward automatically.

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

Free-text keyword (e.g. 'ecksofa') or a category name (e.g. 'sofas', 'laptop', 'waschmaschine') to browse a whole listing -- both go through OTTO's own search route.

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

Keep only products currently showing a reduced price (strike-through original price + discount %). Narrows the same search/category listing, verified live -- combine with Sort = 'Highest discount' to surface the best offers first. No extra fetch.

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

Only return products from these brands, e.g. '99rooms', 'Samsung', 'Jockenhöfer Gruppe'. Match the exact brand name as shown on the site. 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`):

OTTO's own real sort order, applied server-side so paginated results stay correctly ordered across pages.

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

Paste one or more OTTO product pages (.../p/<slug>-<id>/), or search/category listing pages (e.g. .../suche/<term>/ or a category page like .../moebel/sofas/ecksofas/). Pagination continues forward automatically. Filter fields above are ignored in this mode.

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

Adds the full breadcrumb category path, flattened technical specs, seller/partner identity (OTTO vs marketplace partner), EAN/GTIN/SKU, return policy, and full image gallery from the product detail page. Current price, was-price/discount, variant matrix and rating are already included without this toggle. A pasted product URL always fetches this page regardless of the toggle (it is the only source of that item's data) -- the toggle controls whether these extra fields are kept.

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

Fetch each product's native customer reviews: overall rating, review count, and per-review author/location/date/rating/verified-purchase/title/body/helpful-votes. Products with no reviews simply return an empty list. Shares the same product-detail fetch as 'Fetch full product detail' when both are on.

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

Cap on reviews fetched per product when 'Fetch reviews' is on. 0 = all reviews the product detail page renders.

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

Stop after this many result-page fetches per search/category/URL entry. 0 (default) = unlimited -- the run walks the full catalogue and stops at Max products total instead.

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

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

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

Paste a previous run id (or its dataset id) to continue that run: products already collected there are skipped, so this run only returns new products (a delta). Leave empty for a normal run.

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

Governs the product listing/search connection, which works on every Apify plan including the free tier. The product detail and reviews fetch (on by default) always uses a residential connection at extra cost, regardless of this setting.

## `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": "ecksofa",
  "specialsOnly": false,
  "brands": [],
  "sortBy": "RELEVANCE",
  "urls": [
    "https://www.otto.de/suche/ecksofa/"
  ],
  "fetchDetails": false,
  "fetchReviews": true,
  "maxReviewsPerProduct": 10,
  "maxPages": 0,
  "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": "ecksofa",
    "brands": [],
    "urls": [
        "https://www.otto.de/suche/ecksofa/"
    ],
    "proxy": {
        "useApifyProxy": true
    }
};

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

# Run the Actor and wait for it to finish
run = client.actor("abotapi/otto-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": "ecksofa",
  "brands": [],
  "urls": [
    "https://www.otto.de/suche/ecksofa/"
  ],
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call abotapi/otto-de-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "OTTO.de - Prices, Variants, Specs & Reviews",
        "description": "Extract rich product data from OTTO.de across fashion, furniture, electronics and homeware. Search or paste product and category URLs to get prices, discounts, colour and size variants, availability, brand, seller, EAN/GTIN, specifications, categories and customer reviews.",
        "version": "1.0",
        "x-build-id": "w2cyCFPxVOb1ZHM3v"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/abotapi~otto-de-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-abotapi-otto-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~otto-de-scraper/runs": {
            "post": {
                "operationId": "runs-sync-abotapi-otto-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~otto-de-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-abotapi-otto-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 or category name, with real site filters and sort. 'url' scrapes any product, search-result, or category page URL you paste, walking pagination forward automatically.",
                        "default": "search"
                    },
                    "searchTerm": {
                        "title": "Search keyword or category name",
                        "type": "string",
                        "description": "Free-text keyword (e.g. 'ecksofa') or a category name (e.g. 'sofas', 'laptop', 'waschmaschine') to browse a whole listing -- both go through OTTO's own search route."
                    },
                    "specialsOnly": {
                        "title": "Specials / offers only",
                        "type": "boolean",
                        "description": "Keep only products currently showing a reduced price (strike-through original price + discount %). Narrows the same search/category listing, verified live -- combine with Sort = 'Highest discount' to surface the best offers first. No extra fetch.",
                        "default": false
                    },
                    "brands": {
                        "title": "Brands",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Only return products from these brands, e.g. '99rooms', 'Samsung', 'Jockenhöfer Gruppe'. Match the exact brand name as shown on the site. 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",
                            "DISCOUNT",
                            "NEWEST",
                            "RATING"
                        ],
                        "type": "string",
                        "description": "OTTO's own real sort order, applied server-side so paginated results stay correctly ordered across pages.",
                        "default": "RELEVANCE"
                    },
                    "urls": {
                        "title": "URLs to scrape",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Paste one or more OTTO product pages (.../p/<slug>-<id>/), or search/category listing pages (e.g. .../suche/<term>/ or a category page like .../moebel/sofas/ecksofas/). Pagination continues forward automatically. Filter fields above are ignored in this mode.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "fetchDetails": {
                        "title": "Fetch full product detail",
                        "type": "boolean",
                        "description": "Adds the full breadcrumb category path, flattened technical specs, seller/partner identity (OTTO vs marketplace partner), EAN/GTIN/SKU, return policy, and full image gallery from the product detail page. Current price, was-price/discount, variant matrix and rating are already included without this toggle. A pasted product URL always fetches this page regardless of the toggle (it is the only source of that item's data) -- the toggle controls whether these extra fields are kept.",
                        "default": false
                    },
                    "fetchReviews": {
                        "title": "Fetch reviews",
                        "type": "boolean",
                        "description": "Fetch each product's native customer reviews: overall rating, review count, and per-review author/location/date/rating/verified-purchase/title/body/helpful-votes. Products with no reviews simply return an empty list. Shares the same product-detail fetch as 'Fetch full product detail' when both are on.",
                        "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 reviews the product detail page renders.",
                        "default": 10
                    },
                    "maxPages": {
                        "title": "Max pages per search",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Stop after this many result-page fetches per search/category/URL entry. 0 (default) = unlimited -- the run walks the full catalogue and stops at Max products total instead.",
                        "default": 0
                    },
                    "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
                    },
                    "resumeFromRunId": {
                        "title": "Resume from run/dataset id",
                        "type": "string",
                        "description": "Paste a previous run id (or its dataset id) to continue that run: products already collected there are skipped, so this run only returns new products (a delta). Leave empty for a normal run."
                    },
                    "proxy": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Governs the product listing/search connection, which works on every Apify plan including the free tier. The product detail and reviews fetch (on by default) always uses a residential connection at extra cost, regardless of this setting.",
                        "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
