Otto.de Product Price Watch (Germany) avatar

Otto.de Product Price Watch (Germany)

Pricing

from $0.55 / 1,000 product scrapeds

Go to Apify Store
Otto.de Product Price Watch (Germany)

Otto.de Product Price Watch (Germany)

Search otto.de for any term and get one flat row per product: price in EUR, UVP and discount, rating, review count, brand, delivery note, URL, image - and whether each product is new, cheaper or dearer than on the last run.

Pricing

from $0.55 / 1,000 product scrapeds

Rating

0.0

(0)

Developer

Superslow Sloth

Superslow Sloth

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Search otto.de for one or more terms and get one flat row per product: price in EUR, UVP (the crossed-out recommended price) and discount, rating and review count, brand, delivery note, URL and image - and whether each product is new since your last run or changed price. Schedule it daily with Only new and re-priced products on and you get a price-watch feed that costs nothing for products whose price has not moved.

Input

FieldNotes
queriesSearch terms, one per line (staubsauger, akku staubsauger). Each is searched separately; a product two terms both find is returned once, under the first.
maxItemsProducts read per search term (default 100, max 5,000). Otto serves 120 per page.
sorttopseller (default), preis-aufsteigend, preis-absteigend, bewertung, hoechste-reduzierung, neuheiten - Otto's own sort chips. The actor checks which sort the page says it served and stops with a failure on a mismatch, because Otto silently falls back to the default for a value it does not know.
fullPricesSee Which products have a price below. Default on.
changesOnlyReturn and charge only products that are new or re-priced since the last run of the same search.

Which products have a price

This is the one thing to know about otto.de. Its search page is server-rendered, but only the first 18 of the 120 products on a page are rendered with a price (measured 2026-10-07 on staubsauger, offsets 0, 120, 240 and 3,900, and on three other queries). The other 102 are placeholders with an id, a name and a link; the website fills them in with a second request the moment you scroll.

  • fullPrices off reads the page exactly as it is served. Products with a price on the page become rows; placeholders are skipped and not charged (the run log counts them). You get the 18 priced products of every page - a thin slice of the result list, but each row is complete.
  • fullPrices on (default) also calls GET /crocotile/tile/data?variationIds=... - the endpoint the website's own script calls to fill the placeholders in - with the ids of the unpriced products of each page, one extra request per page. Every product becomes a row. Its prices matched the page's own on all 17 products both sources priced.

Output

FieldNotes
changenew, price_drop, price_rise or unchanged, compared with the previous run of the same search.
query, sortThe term that surfaced the product first, and the sort order.
position, sponsoredPlace in the result list (counted across pages) and whether it is a paid placement. Sponsored tiles repeat products that are also listed ordinarily; the product is returned once.
product_id, variation_id, article_numberOtto's ids. A product has one variation per colour or size; the price and the change tracking belong to the variation.
name, brand, url, image_urlurl is https://www.otto.de/p/<slug>/?variationId=<variation_id>.
price, currencyThe selling price as a float, EUR.
is_starting_priceTrue for "ab 3,48 €": the lowest of several variants' prices.
suggested_retail_priceThe crossed-out UVP. Null when the tile shows none.
discount_percentWhole percent below the UVP, computed from the two prices above. It equalled the sale tag Otto prints on every tile checked (about 110). Null without a UVP.
unit_price, unit_price_amount, unit_price_unit"(7,00 €/ 1 Stk)" as 7.0, 1.0, "Stk". Null when Otto prints none.
rating, review_countStar average and number of ratings; both null for an unreviewed product.
availability, delivery_noteInStock and Otto's delivery line, verbatim. The wording changes between requests ("in 4-5 Werktagen bei dir" / "bis Mo., 12. Okt. bei dir") - do not diff it between runs.

Honest nulls

A value the tile does not show is null, never 0 or "". A product with no UVP has discount_percent: null, not 0.

What is not exported

Otto's own earlier price ("Vergleichspreis") exists in only one of the two markups otto.de serves for the same tile (chosen per request: six identical requests gave one markup four times and the other twice), so it would be filled on half the runs and read as a price change on the others. It is left out.

A search never comes back empty

A nonsense term is not a "no results" page on otto.de: xqzvbnmkjhg returned 1,333 unrelated products (a loose match; the nonsense word is still printed in the heading). Check your terms; the actor cannot tell that from a real hit.

Change tracking

Each search (the set of terms and the sort order) has its own memory, kept in a named key-value store on your Apify account (otto-de-products-watch), so it is never visible to anyone else. The first run labels every product new. After that a product is new if the last run did not read it, price_drop / price_rise if its price moved, and unchanged otherwise. The memory keys on the variation id, not the product id, so a tile that starts showing a different colour is new rather than a fake price change.

With changesOnly, unchanged products are neither returned nor charged. maxItems still counts them: it is how much of the result list is watched, so a watch of the top 500 results reads 500 however few moved. Otto's lists are not newest-first (the default is Topseller), so there is no early stop - the run reads maxItems products per term.

Pricing

Pay per event:

  • $0.002 per run (actor-start), charged only after your input is validated - a run that fails on bad input costs nothing.
  • $0.00055 per product row written (product-scraped), i.e. $0.55 per 1,000 products. With changesOnly, unchanged products are not charged.

How it fetches

It reads the same pages otto.de serves to a browser (https://www.otto.de/suche/<term>/?l=gq&o=<offset>&sortiertnach=<sort>, 120 products per page), parsing the product JSON-LD and price markup of each tile; with fullPrices it adds one request per page to /crocotile/tile/data. No account, no login, no cookies. Apify datacenter proxy is the default; a refused request (HTTP 403, 429, 5xx, or a 200 page without results) is retried from a fresh address.