OTTO.de Scraper icon

OTTO.de Scraper

Scrape OTTO.de products by search or URL. Extract prices, discounts, variants, availability, brand, seller, EAN/GTIN, specifications, categories, and…

Start using this actor on Apify ↗Need a custom scraper?Contact us ↗

OTTO.de Scraper at a glance

OTTO.de Scraper is a ready-to-run Apify actor from abotapi for collecting ecommerce data. Its documented output includes product id, product, change type (incremental mode), brand and price, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $1.80 per 1,000 results on the Apify Free plan and from $1.20 on paid plans, with smaller per-run or optional feature charges listed on Apify.

Runs on
Apify cloud: console, API, schedules and integrations
Data type
Ecommerce, Automation, Developer Tools
Region
Europe
Pricing
$1.80 per 1,000 results (Free plan), from $1.20 on paid plans
Output
Documented below · JSON, CSV, Excel
Inputs
23 options

Scrape OTTO.de products by search or URL. Extract prices, discounts, variants, availability, brand, seller, EAN/GTIN, specifications, categories, and customer reviews across fashion, furniture, electronics, and homeware.

What OTTO.de Scraper can do

  • Price and discount, already structured. When a product is marked down, the current price, the original price, the site's discount percent and its own promo label all come from one listing fetch, at no extra cost.
  • Colour variant matrix. Every colour option a product offers is returned with its own variant id and colour code.
  • Specials, first class. specialsOnly narrows any search to only products currently showing a reduced price, and sortBy: DISCOUNT surfaces the biggest reductions first, both driven by the site's own live discount signal.
  • Seller transparency. With Fetch full product detail on, the 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 individual reviews (up to Max reviews per product, 10 by default, or every review the page renders with it set to 0) with author, location, date, star rating, verified-purchase flag, body text and helpful-vote counts, sourced directly from the product page.
  • Rich detail on demand. Full breadcrumb category path, flattened technical specifications (these vary per product category), EAN/GTIN/SKU, the full image gallery and the return policy.

Choose what to collect

These inputs let you configure OTTO.de Scraper - Products, Prices, Variants & Reviews. Open the actor on Apify to enter your values and review the current options.

Supported input fields
InputWhat it controls
modestring · required'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.

Choices: search, url

searchTermstringFree-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.
urlsarrayPaste OTTO search pages (.../suche//), category pages (.../moebel/sofas/ecksofas/), department hubs (.../moebel/), with optional ?sortiertnach= sort or ?marke=&preis= filters, or the internal /dundee/tilelist JSON route (o=offset starts mid-list = partial scope). Product pages (.../p/-/) are also accepted. Leaving this field untouched scrapes one example of each shape (see README). Rival alias: startUrls.
specialsOnlybooleanKeep 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.
brandsarrayOnly 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.
minRatingintegerOnly return products rated at or above this many stars, 1-5.
minPricenumberOnly return products priced at or above this amount, in euros.
Show 16 more inputs
More input fields
InputWhat it controls
maxPricenumberOnly return products priced at or below this amount, in euros.
sortBystringOTTO's own real sort order, applied server-side so paginated results stay correctly ordered across pages.

Choices: RELEVANCE, PRICE_ASC, PRICE_DESC, DISCOUNT, NEWEST, RATING

fetchDetailsbooleanAdds 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.
fetchReviewsbooleanFetch 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.
maxReviewsPerProductintegerCap on reviews fetched per product when 'Fetch reviews' is on. The detail page renders about a dozen; a higher cap reads further pages of OTTO's own review list. 0 = all reviews the product detail page renders.
maxPagesintegerStop after this many result-page fetches per search/category/URL entry. 0 (default) = no explicit limit -- the run walks the catalogue and stops at Max products total, or at an internal hard cap of 1000 pages per entry.
maxItemsintegerHard cap on total products returned across every search/category/URL entry. 0 = the maximum of 100000 (still bounded by Max pages per search).
resumeFromRunIdstringPaste 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. For recurring daily/weekly monitoring of the same search, use Incremental mode below instead.
incrementalModebooleanTurn this on for daily or recurring monitoring. The first run returns all matching products as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED products. A product counts as UPDATED when any returned field changes (price, original price, availability, name, images, variants, and the detail and review fields when those are on), and changedFields names them; integral prices such as 25 and 25.0 are the same value. Nothing is excluded by default; use "Ignore fields when detecting changes" to leave out a noisy field. Turn on "Emit unchanged" or "Emit expired" only when you also want those products returned (and billed). State is kept separately for each search/URL and detail-mode setup; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.
stateKeystringOptional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the search/URL and detail settings -- different searches then never mix state with each other.
emitUnchangedbooleanOff by default. Turn on to also return products that have not changed since the last run, marked UNCHANGED. This returns -- and bills -- extra rows you already have, so leave it off unless you specifically want the full snapshot every run.
emitExpiredbooleanOff by default. Turn on to also return products that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search -- not when Max products capped it or when Resume was used. This returns -- and bills -- extra synthetic rows, so leave it off unless you need expiry tracking.
ignoreFieldsForChangesarrayOptional. Top-level field names (for example promoLabel) to leave out of UPDATED change detection and out of changedFields, on top of the built-in handling. The field is still returned in the output. Use it when a field turns out to be noisy in your setup. Changing this list never causes a one-time wave of UPDATED rows.
mcpConnectorsarrayOptionally 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).
notionParentPageUrlstringURL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.
maxNotifyListingsintegerCap on items written to each connector per run. Does not affect the dataset.

Fields in the output

The documented dataset includes the fields below. Availability can depend on the source page and selected mode.

productIdProduct ID (text)
nameProduct (text)
changeTypeChange type (incremental mode) (text)
brandBrand (text)
pricePrice (number)
currencyCurrency (text)
originalPriceOriginal price (number)
discountPercentDiscount % (number)
isOnSpecialOn special (boolean)
availabilityAvailability (text)
ratingRating (number)
reviewCountReviews (number)
Show 20 more fields
urlURL (link)
imageImage (image)
changedFieldsChanged fields (incremental mode) (array)
firstSeenAtFirst seen (incremental mode) (date)
lastSeenAtLast seen (incremental mode) (date)
linkLink (same as URL) (link)
skuSKU (product details on) (text)
priceCurrencyPrice currency (same as Currency) (text)
aggregateRatingAggregate rating (ratingValue, reviewCount) (object)
descriptionDescription (product details on) (text)
variantsColour/variant matrix (variationId, colour, availability) (object)
reviewsreviews
eanEAN (text)
gtinGTIN (text)
articleNumberArticle number (text)
specsSpecifications (object)
sellerSeller (object)
returnPolicyReturn policy (object)
breadcrumbBreadcrumb (array)
imagesGallery (array)

Example output

An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.

{
  "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,
  "currency": "EUR",
  "originalPrice": 1599,
  "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",
  "specs": {
    "Höhe": "85 cm",
    "Breite": "289 cm",
    "Polsterung": "Schaumstoff"
  },
  "seller": {
    "name": "Sample Home Brands GmbH",
    "partnerId": "1000000",
    "sellerType": "MARKETPLACE_PARTNER"
  },
  "returnPolicy": {
    "days": 30,
    "freeReturn": true
  },
  "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"
      }
    ]
  }
}

Ways to use this data

  • Deal hunters and price trackers: monitor a category or brand for the current price, the original price and the discount percent so you can time a purchase or a repricing decision.
  • Marketplace and assortment research: compare OTTO's own listings against third-party marketplace partners selling the same or similar products, and see who actually fulfils each one.
  • Review and reputation analysis: build a dataset of native customer reviews per product or category for sentiment, quality, or complaint analysis.
  • Catalogue monitoring: track new, updated and removed products in a search or category on a recurring schedule.
  • Product data enrichment: pull structured specs, EAN/GTIN/SKU, images and return policy into your own catalogue or PIM system.

Before you run

Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.

Questions about this actor

What data does OTTO.de Scraper return?

The documented output for OTTO.de Scraper includes product id, product, change type (incremental mode), brand, price, currency, original price and discount %. Availability of each field depends on the source page and the selected mode.

How much does OTTO.de Scraper cost?

It costs $1.80 per 1,000 results on the Apify Free plan and from $1.20 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.

Which dataset views are available?

The dataset has these views: Products (overview), Variants (nested), Reviews (one row per review), Product details (needs Fetch full product detail) and Changes (incremental mode).

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

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated products, and unchanged ones are not returned or billed unless you turn that on too.

Why did specialsOnly return nothing for my pasted product link?

The product detail page does not expose the same special-offer signal a listing card does, so Specials / offers only always excludes a single pasted product URL, whether or not that product is actually discounted. Leave it off when pasting one product link, and use it on a search or category URL or link instead.

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

If the site's response no longer matches any shape this actor recognizes, the run fails with a clear message instead of quietly returning zero products, so "no results for this search" is never confused with "the extraction broke". A genuinely empty search still completes normally with zero items. If the connection is repeatedly refused partway through, the run keeps everything already collected and stops cleanly rather than retrying forever.

Ready to collect with OTTO.de Scraper?

Run it on Apify with your own input and export the results as JSON, CSV or Excel.