# Idealo Price History & Deal Intelligence (`axlymxp/idealo-price-history-scraper`) Actor

Track idealo prices over time. Get up to a year of daily prices per product across 6 markets (DE, AT, UK, FR, IT, ES) plus all-time-low flags, % off the period high, volatility, drop counts and cross-border comparison. Feed repricing, deal alerts and MAP checks. Pay per result.

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

## Pricing

from $12.00 / 1,000 dataset items

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Idealo Price History & Deal Intelligence

Most price scrapers tell you what something costs **today**. This one tells you
what it has cost **every day for the past year** — and what that means.

Give it product URLs, product IDs or search terms and get back, per product: up
to 365 daily price points, the period low and high with their dates, how far
below its peak the price sits right now, volatility, how many times it dropped,
the biggest single drop, an at-a-period-low flag, idealo's own bargain
indicator, today's cheapest shop, and the same product's price in the other
idealo markets.

Covers **six markets**: Germany, Austria, the United Kingdom, France, Italy and
Spain.

### Who uses this

| You are…                          | You get                                                                       |
| --------------------------------- | ----------------------------------------------------------------------------- |
| **Pricing / repricing team**      | The real price floor and ceiling per SKU, not a single noisy snapshot         |
| **Deal site / affiliate**         | A filtered feed of products genuinely at a period low — not fake "was" prices |
| **Brand / MAP compliance**        | Evidence of when and how far a product fell below your price floor            |
| **Category buyer / merchandiser** | Seasonality and volatility per product before you commit stock                |
| **Cross-border seller**           | Where in Europe the same product is systematically cheaper                    |
| **Analyst / researcher**          | Clean daily price time series for inflation, elasticity and trend work        |

### Why history beats a snapshot

A single scrape cannot tell a real discount from a manufactured one. A product
listed at €559 might be at its cheapest ever — or €40 above where it sat all
summer. This Actor returns `pct_below_period_high`, `is_period_low`,
`min_price_date` and the full series, so "is this actually a good price?" becomes
a column you can sort on.

### Output fields

| Field                                                                                          | Type    | Description                                              |
| ---------------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------- |
| `product_id`, `title`, `url`, `image`                                                          | string  | Product identity — the ID is shared across all 6 markets |
| `market`, `country`, `currency`, `period`                                                      | string  | Which market and window the series covers                |
| `data_points`, `days_tracked`                                                                  | integer | Size of the returned series                              |
| `period_start_date`, `period_end_date`                                                         | string  | First and last observation dates                         |
| `current_price`                                                                                | number  | Most recent price in the series                          |
| `min_price`, `min_price_date`                                                                  | mixed   | Period low and when it happened                          |
| `max_price`, `max_price_date`                                                                  | mixed   | Period high and when it happened                         |
| `avg_price`, `median_price`                                                                    | number  | Central tendency across the period                       |
| `price_change_abs`, `price_change_pct`                                                         | number  | Movement from the start of the period to now             |
| `pct_below_period_high`                                                                        | number  | The real discount right now                              |
| `pct_above_period_low`                                                                         | number  | How much you'd overpay versus the cheapest it has been   |
| `is_period_low`, `is_period_high`                                                              | boolean | Sortable deal flags                                      |
| `volatility_pct`                                                                               | number  | Std-dev as a percentage of the mean                      |
| `price_changes`, `drops`, `rises`                                                              | integer | How actively the price moves                             |
| `biggest_drop_abs`, `biggest_drop_pct`                                                         | number  | Largest single-step fall in the period                   |
| `trend_30d_pct`                                                                                | number  | Short-term direction over the last 30 observations       |
| `is_bargain`, `bargain_details`                                                                | mixed   | Idealo's own bargain indicator                           |
| `best_shop_name`, `best_price`, `best_total_price`, `best_offer_url`                           | mixed   | Today's cheapest merchant                                |
| `offer_count`, `shop_count`                                                                    | integer | Live competition on the product                          |
| `cross_market_prices[]`, `cheapest_market`, `cheapest_market_price`, `cross_market_saving_pct` | mixed   | Cross-border comparison                                  |
| `price_series[]`                                                                               | array   | The raw `[{date, price}]` history, oldest first          |
| `scraped_at`                                                                                   | string  | UTC timestamp                                            |

### High-value use cases

1. **Automated deal feed** — set `onlyDeals` or `minDropFromHighPct: 20` and
   schedule hourly; every row is a product genuinely near its floor.
2. **Repricing guard rails** — use `min_price`, `median_price` and
   `volatility_pct` per SKU to set price bands that survive competitor noise.
3. **MAP violation evidence** — the dated series shows exactly when a product
   went below your minimum advertised price and by how much.
4. **Cross-border sourcing** — compare markets and sort by
   `cross_market_saving_pct` to find products consistently cheaper in another
   country.
5. **Buying-season research** — `min_price_date` across a category reveals when
   a product class actually bottoms out, instead of guessing at Black Friday.

### Input parameters

| Parameter             | Type    | Default | Description                                               |
| --------------------- | ------- | ------- | --------------------------------------------------------- |
| `market`              | select  | `de`    | `de`, `at`, `uk`, `fr`, `it`, `es`                        |
| `products`            | array   | —       | Product URLs (any market) or bare numeric product IDs     |
| `searchTerms`         | array   | —       | Resolve products by keyword, then pull each one's history |
| `period`              | select  | `1Y`    | `1M`, `3M`, `6M`, `1Y`                                    |
| `compareMarkets`      | array   | `[]`    | Extra markets to compare the same product against         |
| `includeCurrentOffer` | boolean | `true`  | Add today's cheapest shop, price and offer count          |
| `includeSeries`       | boolean | `true`  | Include the raw daily `[{date, price}]` array             |
| `onlyDeals`           | boolean | `false` | Emit only products at a period low or flagged a bargain   |
| `minDropFromHighPct`  | integer | `0`     | Only emit products at least this far below their peak     |
| `maxItems`            | integer | `100`   | Stop after this many products (0 = unlimited)             |
| `maxPagesPerTerm`     | integer | `2`     | Search pages walked per term when resolving products      |
| `proxyConfiguration`  | object  | off     | Optional — runs fine without a proxy                      |

At least one of `products` or `searchTerms` is required.

### Example input

```json
{
    "market": "de",
    "products": ["203235721"],
    "searchTerms": ["iphone 15"],
    "period": "1Y",
    "compareMarkets": ["it", "uk"],
    "includeCurrentOffer": true,
    "onlyDeals": false,
    "maxItems": 25
}
```

### Example output

```json
{
    "product_id": "203235721",
    "title": "Apple iPhone 15",
    "url": "https://www.idealo.de/preisvergleich/OffersOfProduct/203235721_-iphone-15-apple.html",
    "market": "de",
    "country": "Germany",
    "currency": "EUR",
    "period": "1Y",
    "data_points": 335,
    "period_start_date": "2025-09-01",
    "period_end_date": "2026-09-01",
    "current_price": 559.9,
    "min_price": 499.0,
    "min_price_date": "2025-11-28",
    "max_price": 749.0,
    "max_price_date": "2025-09-14",
    "avg_price": 588.41,
    "median_price": 579.9,
    "price_change_abs": 30.0,
    "price_change_pct": 5.66,
    "pct_below_period_high": 25.25,
    "pct_above_period_low": 12.2,
    "is_period_low": false,
    "is_period_high": false,
    "volatility_pct": 8.14,
    "price_changes": 122,
    "drops": 63,
    "rises": 59,
    "biggest_drop_abs": 41.0,
    "biggest_drop_pct": 6.72,
    "trend_30d_pct": 1.82,
    "is_bargain": false,
    "best_shop_name": "Cyberport",
    "best_price": 559.9,
    "offer_count": 147,
    "shop_count": 48,
    "cross_market_prices": [
        {
            "market": "it",
            "country": "Italy",
            "currency": "EUR",
            "current_price": 484.0,
            "min_price": 449.0,
            "data_points": 322
        },
        {
            "market": "uk",
            "country": "United Kingdom",
            "currency": "GBP",
            "current_price": 423.99,
            "min_price": 399.0,
            "data_points": 298
        }
    ],
    "cheapest_market": "uk",
    "cheapest_market_price": 423.99,
    "cross_market_saving_pct": -24.27,
    "price_series": [{ "date": "2025-09-01", "price": 529.9 }],
    "scraped_at": "2026-09-01T10:31:07Z"
}
```

> Cross-market prices are reported in each market's own currency (`currency` per
> entry). The UK series is in GBP — convert before comparing it to a EUR market.

### Scheduling & integrations

Schedule daily or hourly runs from the Apify Console to keep a rolling price
archive of your catalogue. Export as JSON, CSV, Excel or XML, or push results by
webhook into Google Sheets, Make, Zapier, Amazon S3 or your own API. Long runs
checkpoint after every 20 products, so an interrupted run resumes instead of
re-emitting rows you already paid for.

### Use it from an AI assistant (MCP)

Callable through Apify's MCP server, so Claude, ChatGPT or any MCP-capable agent
can run it directly:

```
https://mcp.apify.com/?actors=axlymxp/idealo-price-history-scraper
```

Ask *"has the iPhone 15 ever been cheaper than it is today on idealo?"* and your
assistant will run the Actor and read the answer out of the dataset.

### FAQ

**Where does the history come from?**
Idealo tracks its own daily price index per product and market. The Actor reads
that series directly, so you get real historical data on the first run — you do
not have to build up a history yourself over months.

**How far back does it go?**
Up to one year (`1Y`, roughly 335 daily points). Shorter windows (`1M`, `3M`,
`6M`) return proportionally fewer points and run faster.

**Does every product have history?**
No. Very new or very rare products may return an empty series. Those rows are
skipped and logged rather than emitted as empty, so you are not charged for
them.

**Do I need a proxy?**
No. The Actor works without one. A proxy is supported for very large runs or
rate-limited regions.

**Can I compare markets in one run?**
Yes — set `compareMarkets`. Note that each market reports in its own currency;
the UK series is GBP while the others are EUR.

**How do I build a deal feed?**
Set `onlyDeals: true` (period low or idealo bargain flag) or
`minDropFromHighPct` to a threshold like 20, add your search terms, and schedule
it. Filtered-out products are not pushed, so you only pay for real hits.

**Is this legal?**
The Actor collects publicly available product and price information. You are
responsible for using the data in line with idealo's terms and applicable law.

# Actor input Schema

## `market` (type: `string`):

Which idealo country market the price history is taken from.

## `products` (type: `array`):

Idealo product page URLs (any market) or bare numeric product IDs. Product IDs are the same across all six country sites.

## `searchTerms` (type: `array`):

Resolve products by keyword first, then pull the price history of every match. Use this to track a whole product family.

## `period` (type: `string`):

How far back to pull daily prices. 1Y returns roughly 335 daily data points.

## `compareMarkets` (type: `array`):

Also pull the same product's price series from these markets and report the cheapest one — the cross-border arbitrage view. Adds one request per market per product.

## `includeCurrentOffer` (type: `boolean`):

Fetch the live product page for the current cheapest shop, price, offer count and product title. Adds one request per product.

## `includeSeries` (type: `boolean`):

Include the raw \[{date, price}] array in each row. Turn off if you only want the computed analytics.

## `onlyDeals` (type: `boolean`):

Emit a row only when the product is at its lowest price of the selected period, or is flagged a bargain by idealo. Great for deal feeds.

## `minDropFromHighPct` (type: `integer`):

Only emit products currently at least this many percent below their highest price in the period. 0 disables the filter.

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

Stop after this many products (0 = unlimited).

## `maxPagesPerTerm` (type: `integer`):

Result pages to walk when resolving products from search terms. Each page holds up to 36 products.

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

Optional. The scraper works without a proxy; add one for very large runs or if your region is rate limited.

## Actor input object example

```json
{
  "market": "de",
  "products": [
    "203235721",
    "https://www.idealo.de/preisvergleich/OffersOfProduct/203247542_-iphone-15-128gb-schwarz-apple.html"
  ],
  "searchTerms": [
    "iphone 15",
    "dyson v15"
  ],
  "period": "1Y",
  "compareMarkets": [],
  "includeCurrentOffer": true,
  "includeSeries": true,
  "onlyDeals": false,
  "minDropFromHighPct": 0,
  "maxItems": 100,
  "maxPagesPerTerm": 2,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

One row per product: the daily price series plus computed deal and volatility analytics.

# 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 = {
    "products": [
        "203235721"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("axlymxp/idealo-price-history-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 = { "products": ["203235721"] }

# Run the Actor and wait for it to finish
run = client.actor("axlymxp/idealo-price-history-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "products": [
    "203235721"
  ]
}' |
apify call axlymxp/idealo-price-history-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axlymxp/idealo-price-history-scraper"
        }
    }
}

```

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

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/8tj66KHTGDVQebfgR/builds/8ufY43KvgFEnbyNEA/openapi.json
