# Billiger.de Scraper (`normdata/billiger-scraper`) Actor

Scrape billiger.de, the German price comparison: lowest price, every shop offer with shipping and delivery, EAN, specs, test scores, 6 month price history and price rating. Search or categories, 11 filters, variants, price change monitoring. Fast, no proxy.

- **URL**: https://apify.com/normdata/billiger-scraper.md
- **Developed by:** [Norm Data](https://apify.com/normdata) (community)
- **Categories:** E-commerce, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 product scrapeds

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

![Norm Data](https://raw.githubusercontent.com/FabriAV/normdata/refs/heads/main/assets/banner_norm2.png)

## 🛒 Billiger.de Scraper - Prices, Shop Offers, EAN & Price History

Extract products from **billiger.de**, one of Germany's biggest price comparison sites. For every product you get the **lowest price, number of shop offers, rating and reviews, price drop badge, energy class and key specs**. Turn on **Product details** for **every shop offer** (shop, marketplace seller, price, old price, shipping, total, delivery time, returns, shop rating, link), the **cheapest shop**, **EAN**, color and size, **every spec**, **magazine test scores with pros and cons**, the bestseller rank, **used (B-Ware) offers**, the **daily price history of the last 6 months** with the 30, 90 and 180 day lows, and the site's own **price rating** (low, normal or high). Search by words or categories, use 11 filters, get one row per variant, paste links, or run it on a schedule to get **only price changes**.

### 🎯 Who uses it?

#### 🏪 Retailers and e-commerce teams

See what every German shop charges for the products you sell, with shipping, delivery time and marketplace sellers. Find your products by EAN in the results.

#### 🏭 Brands and manufacturers

Check how your products are priced across Amazon, eBay, OTTO, MediaMarkt and hundreds of other shops, and spot sellers under your recommended price.

#### 📈 Pricing and market analysts

Follow 6 months of daily prices per product, see which products are at a low, normal or high price today, and compare whole categories by brand, price and rating.

#### 🛍️ Deal sites and affiliates

Find products at their 6 month low, marked as deals or with the biggest price drops, with the cheapest shop's link.

### ✨ What it does

- **Search** by words (like "iphone 17" or "airpods pro") or **categories** by German name, English name, ID or link (like "Fernseher", "laptops" or 2303).
- **Whole categories, not just the first 1,440.** The site shows at most 1,440 products per list; bigger lists are read in price slices, so a 10,000 product category comes back complete.
- **Product details add-on:** every shop offer, cheapest shop with shipping and delivery, EAN, color, size, model year, every spec, test score and test count, pros and cons, bestseller rank, used offers, 6 month daily price history, 30, 90 and 180 day lows, 180 day high and average, and the site's price rating.
- **One row per variant:** product families (every color and storage of a phone) can be split into one row per variant with its own price and offer count.
- **11 filters:** brands, shops, price range, rating, reviews, number of offers, price drop, available now, deals only, plus 3 sort orders.
- **Or paste links.** Category pages (with any filters set on the site), search pages and product pages. Filters are ignored with links.
- **Monitoring:** run it on a schedule with **Only new products**, or with **Only price changes** to get just the products whose price moved, with the previous price and the change.

### 🏆 Why this scraper

- **The only billiger.de actor with price history.** 6 months of daily prices, the 30, 90 and 180 day lows, and the site's own "is this a good price" rating (October 2026).
- **Complete categories.** Price slicing reaches every product of a category, past the site's 1,440 limit (10,670 of 10,672 notebooks in our test).
- **More data per product.** Every shop offer with shipping, total, delivery, returns and marketplace seller, EAN, all specs, tests, pros and cons, used offers.
- **Values you can trust.** In our tests the price, EAN, test score, reviews, cheapest shop, offer counts and bestseller rank matched the product page for every product checked.
- **Fast.** About 1,000 products in 10 to 15 seconds, or 45 seconds with Product details.
- **Nothing to set up.** No proxy, no login, no browser.

### ⚖️ How it compares

| Capability | This actor | Other billiger.de actors |
|---|:--:|:--:|
| Search results with lowest price | **yes** | yes |
| Shop offers with shipping and delivery | **yes** | partly |
| Whole categories past 1,440 products | **yes** | no |
| EAN, specs, tests, pros and cons | **yes** | partly |
| 6 month price history, lows and price rating | **yes** | no |
| Used (B-Ware) offers and lowest used price | **yes** | no |
| One row per variant | **yes** | no |
| Filters (brand, shop, price, rating, reviews, offers, drop, stock, deals) | **11** | few or none |
| Only new products / only price changes monitoring | **yes** | no |
| Proxy | **none needed** | varies |

### 📦 What data you get

| Field | Description |
| --- | --- |
| `imageUrl` | Product photo. |
| `productId`, `type` | billiger.de ID and type: "product" (one exact item) or "variantGroup" (a family with variants, like every color of a phone). |
| `name`, `brand` | Product name and brand. |
| `price` | Lowest price of a new item, in euros, as the site shows it. For a family, the lowest of all its variants. |
| `previousPrice`, `priceChange` | With "Only price changes": the price in the last run and the change. |
| `highestPrice`, `lowestUsedPrice` | *(Product details)* Highest shop price for a new item, and the cheapest used (B-Ware) offer. |
| `priceRating` | *(Product details)* The site's rating of today's price against the last 6 months: low, normal or high. |
| `lowestPrice30Days`, `lowestPrice90Days`, `lowestPrice180Days`, `highestPrice180Days`, `averagePrice180Days` | *(Product details)* Lowest price of the last 30, 90 and 180 days, highest and average of 180 days, from the daily price history. |
| `discountPercent` | The site's price drop badge ("- 24%") on the list. |
| `offerCount`, `newOfferCount`, `inStockOfferCount`, `usedOfferCount` | Shop offers for a new item; with details also offers available now and used (B-Ware) offers. |
| `bestShop`, `bestSeller`, `bestShopPriceWithShipping`, `bestShopShipping`, `bestShopDelivery` | *(Product details)* Shop with the lowest price (and the marketplace seller), with its price including shipping, shipping cost and delivery time. |
| `rating`, `reviewCount` | User rating (1 to 5) and number of reviews. |
| `testScore`, `testCount` | *(Product details)* Average score of the magazine tests (1 to 5) and how many tests. |
| `bestsellerRank`, `bestsellerCategory` | *(Product details)* Bestseller rank ("Nr. 1 in Smartphone") and its category. |
| `energyClass` | EU energy class (A to G). |
| `keySpecs` | Main specs the list shows for some categories (TVs, laptops...). |
| `category`, `categoryPath`, `categoryId` | *(Product details)* Category, its full path and its ID. |
| `ean`, `color`, `size` | *(Product details)* EAN barcode, color and size or storage of an exact product. |
| `modelYear` | *(Product details)* Model year. |
| `variantGroupId`, `variantCount` | *(Product details)* The family a product belongs to, and how many variants a family has. |
| `description` | *(Product details)* Test summary, when the product has one. |
| `source` | The search, category or link it came from. |
| `topPrice` | The site marks it as a "Top Preis". |
| `url` | Product page. |
| `pros`, `cons` | *(Product details)* Pros and cons from the magazine tests. |
| `specs` | *(Product details)* Every spec on the product page, with its group (display, battery, weight...). |
| `variants` | *(Product details)* For a family: every variant with its EAN, color, size, lowest and highest price, offer count and link. |
| `offers` | *(Product details)* Every shop on the product page with its best offer: shop, marketplace seller, offer title, price (and the old price when reduced), shipping, total, delivery time, in stock, free returns, promotion, shop rating and reviews, more offers from that shop, and the link. |
| `priceHistory` | *(Product details)* Lowest price of each day of the last 6 months. |
| `listedSince`, `lowestPrice180DaysDate` | *(Product details)* Month the product was first listed, and the day of the 180 day low. |
| `scrapedAt` | When this row was saved. |
| `error` | Only present when a row failed. The fields that loaded are still there. |

Fields marked *Product details* only appear when that add-on is on.

#### Example row (trimmed)

```json
{
  "imageUrl": "https://cdn.billiger.com/dynimg/yYnTIG4YAQJof0p75-xL_Qu61LZG4EHHKhE8nUhH7Pc88MgR1b3VHcWvS03VxtgwE_6fqdh9z8WLjrrsJwNUIGDcccN3OMLrAq472WZQUIL/Apple-iPhone-17-256-GB-Weiss.webp",
  "productId": "5380810032",
  "type": "product",
  "name": "Apple iPhone 17 256 GB Weiß",
  "brand": "Apple",
  "price": 859,
  "highestPrice": 1791.26,
  "lowestUsedPrice": 779,
  "priceRating": "normal",
  "lowestPrice30Days": 850,
  "lowestPrice90Days": 619.5,
  "lowestPrice180Days": 619.5,
  "highestPrice180Days": 919,
  "averagePrice180Days": 797.55,
  "offerCount": 49,
  "newOfferCount": 49,
  "inStockOfferCount": 40,
  "usedOfferCount": 3,
  "bestShop": "ebay.de",
  "bestSeller": "nova-click",
  "bestShopPriceWithShipping": 859,
  "bestShopShipping": 0,
  "bestShopDelivery": "11-20 Werktage",
  "rating": 4.6,
  "reviewCount": 150,
  "testScore": 4.5,
  "testCount": 23,
  "bestsellerRank": 3,
  "bestsellerCategory": "Smartphone",
  "energyClass": "A",
  "category": "Handys ohne Vertrag",
  "categoryPath": "Handy & Telefon > Handys ohne Vertrag",
  "categoryId": "4373",
  "ean": "0195950643787",
  "color": "Weiß",
  "size": "256 GB",
  "modelYear": 2025,
  "variantGroupId": "114326",
  "source": "https://www.billiger.de/products/5380810032-apple-iphone-17-256-gb-weiss",
  "topPrice": false,
  "url": "https://www.billiger.de/products/5380810032-apple-iphone-17-256-gb-weiss",
  "pros": ["Hervorragende Akkulaufzeit", "Starkes 120-Hertz-OLED-Display", "Sehr gute Dual-Kamera"],
  "cons": ["Keine Telezoom-Kamera", "Apple Intelligence noch ausbaufähig", "Dynamic Island verdeckt Inhalte"],
  "specs": [{ "group": "Allgemein", "name": "Marke", "value": "Apple" }],
  "offers": [
    { "shop": "ebay.de", "shopId": "10992", "seller": "nova-click", "marketplace": true, "title": "Apple iPhone 17 256GB Weiß White Neu vom Händler ohne SIMlock + OVP", "price": 859, "oldPrice": null, "shipping": 0, "totalPrice": 859, "delivery": "11-20 Werktage", "inStock": true, "freeReturns": null }
  ],
  "priceHistory": [{ "date": "2026-04-26", "price": 747.9 }],
  "listedSince": "2025-09",
  "lowestPrice180DaysDate": "2026-09-02",
  "scrapedAt": "2026-10-24T21:26:41.402Z"
}
```

### 💡 Use cases

**Every shop's price for the latest iPhones, with price history:**

```json
{
  "searchTerms": ["iphone 17"],
  "includeDetails": true
}
```

**Samsung and LG TVs from 500 to 1,500 €, available now, cheapest first:**

```json
{
  "categories": ["Fernseher"],
  "brands": ["Samsung", "LG"],
  "minPrice": 500,
  "maxPrice": 1500,
  "onlyInStock": true,
  "sort": "price"
}
```

**Well rated headphones sold on amazon.de:**

```json
{
  "categories": ["Kopfhörer"],
  "shops": ["amazon.de"],
  "minRating": 4.5,
  "minReviews": 50
}
```

**Every notebook on the site (about 10,000):**

```json
{
  "categories": ["Notebooks"]
}
```

**Daily price changes for a whole category (schedule this run):**

```json
{
  "categories": ["Handys ohne Vertrag"],
  "onlyPriceChanges": true,
  "monitorName": "phones-daily"
}
```

**Links (filters are ignored):**

```json
{
  "startUrls": [
    { "url": "https://www.billiger.de/show/kategorie/2060.htm?filter=f_brand_2220&order=s_price" },
    { "url": "https://www.billiger.de/search?searchstring=airpods" },
    { "url": "https://www.billiger.de/baseproducts/114326-apple-iphone-17" }
  ],
  "includeDetails": true
}
```

### ⚙️ How the input is organised

| Section | What it's for |
| --- | --- |
| **Maximum results** | Always first, caps the whole run. Empty means no limit. |
| **What to scrape** | Search, categories, product details (offers, EAN, specs, tests, price history) and one row per variant. |
| **Filters** | Brands, shops, minimum price (€), maximum price (€), minimum rating, minimum reviews, minimum offers, minimum discount (%), only available now, only deals and sort. |
| **Monitoring** | Only new products, only price changes and monitor name. |
| **Links** | Links instead of the fields above. Filters are ignored with links. |

### 💰 Pricing

Pay-per-event: a one-time **$0.003** when the run starts, plus a price per product saved to your dataset. The price depends on your Apify plan tier:

| Plan | Per product | Per 1,000 products |
| --- | --- | --- |
| Free | $0.013 | $13 |
| Bronze | $0.012 | $12 |
| Silver | $0.011 | $11 |
| Gold | $0.010 | $10 |

**Product details add-on:** when **Product details** is on, each product saved with its details adds one more charge:

| Plan | Per product | Per 1,000 products |
| --- | --- | --- |
| Free | $0.014 | $14 |
| Bronze | $0.013 | $13 |
| Silver | $0.012 | $12 |
| Gold | $0.011 | $11 |

One row carries all the shop offers, so you pay once per product, not once per shop. Products whose page could not be read pay only the base price, and products left out by filters are free. New Apify accounts start with $5 in free credit. On the Free plan, a run saves up to 10 products.

### 🚀 Run it

1. Create a free Apify account with $5 in credit.
2. Open the Billiger.de Scraper.
3. Type a search or a category, then click **Start**.
4. Export the results as CSV, Excel, JSON or XML from the Dataset tab.

### 🤖 Use with AI agents (MCP)

Connect the [Apify MCP server](https://mcp.apify.com) to Claude, ChatGPT, Cursor or any MCP client, then ask in plain words, for example: *"Find the cheapest German shop for the AirPods Pro 3 on billiger.de and tell me if today's price is low for the last 6 months"*. The agent runs this Actor and reads the results.

### 🔧 Troubleshooting

- **A category was searched as words.** The log says so and names the categories those words appear in, with their IDs. Put one of the IDs in Categories to read just that category.
- **A search found fewer products than the site says.** The site's count includes single shop ads that are not matched to a product; only products are saved.
- **A product family is one row.** Families like "Apple iPhone 17" are one row with their lowest price. Turn on **One row per variant** to get every color and storage.
- **The 30 day low is lower than today's price.** A shop had a short deal in the last 30 days. The price history shows the day.
- **EAN, color or size is empty.** Families have no single EAN (see `variants`), and some products have none on the site.
- **Rating is empty.** The product has no user reviews yet.

### ❓ FAQ

**How many products are there?** Millions, in about 300 main categories. A search or category is read completely; there is no 1,440 limit.

**Are prices in euros?** Yes, as billiger.de shows them, VAT included.

**Which shops are covered?** Every shop billiger.de lists: amazon.de, eBay, OTTO, MediaMarkt, Saturn, Kaufland, Cyberport, notebooksbilliger and hundreds more, with the marketplace seller when there is one.

**Is it legal?** It reads public price data, the same any visitor sees. Check the site's terms and your local laws for your use.

# Actor input Schema

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

Stop after this many products in total (over every search and category). Leave empty for no limit. The Apify Free plan is always capped at 10.

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

Search words, like "iphone 17", "airpods pro" or "lego technic". Words the site knows as a category (like "kaffeemaschine") open that category.

## `categories` (type: `array`):

Category names in German, like "Fernseher", "Notebooks", "Kaffeevollautomaten" or "Sneaker", a category ID (4373) or a category link. Lists of more than 1,440 products (the most the site shows at once) are read in price slices, so every product is reached.

## `includeDetails` (type: `boolean`):

Open every product page and add: every shop offer (shop, seller, price, shipping, total, delivery time, returns, shop rating, link), cheapest shop, EAN, color and size, all specs, test score and pros and cons, bestseller rank, used (B-Ware) offers, the 6 month daily price history with 30, 90 and 180 day lows, and the site's price rating (low, normal, high). One extra request per product, charged as an add-on only for rows saved with it.

## `expandVariants` (type: `boolean`):

Product families (like "Apple iPhone 17" with every color and storage) become one row per variant, each with its own price, offer count and link (and EAN, color and size with Product details). Without it, a family is one row with its lowest price.

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

Only these brands, like "Apple", "Samsung" or "Sony".

## `shops` (type: `array`):

Only products sold by these shops, like "amazon.de", "OTTO", "MediaMarkt" or "Cyberport".

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

Lowest price at least this much.

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

Lowest price at most this much.

## `minRating` (type: `number`):

Only products rated at least this much by users (1 to 5).

## `minReviews` (type: `integer`):

Only products with at least this many user reviews.

## `minOffers` (type: `integer`):

Only products with at least this many shop offers.

## `minDiscount` (type: `integer`):

Only products with a price drop mark of at least this much (the site's "- 24%" badge).

## `onlyInStock` (type: `boolean`):

Only products a shop can deliver right away ("sofort lieferbar").

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

Only products the site marks as deals ("Deals & Schnäppchen").

## `sort` (type: `string`):

Order of the results.

## `onlyNew` (type: `boolean`):

Skip products saved by earlier runs with the same monitor name.

## `onlyPriceChanges` (type: `boolean`):

Save only products whose lowest price changed since the last run with the same monitor name (plus products not seen before), with the previous price and the change. The first run saves everything.

## `monitorName` (type: `string`):

Runs with the same name share their history. Use a different name for each schedule.

## `startUrls` (type: `array`):

Category pages (https://www.billiger.de/show/kategorie/2060.htm, with any filters and sort set on the site), search pages (https://www.billiger.de/search?searchstring=airpods) or product pages (https://www.billiger.de/products/... or /baseproducts/...).

## Actor input object example

```json
{
  "maxItems": 10,
  "searchTerms": [
    "iphone 17"
  ]
}
```

# Actor output Schema

## `results` (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 = {
    "maxItems": 10,
    "searchTerms": [
        "iphone 17"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("normdata/billiger-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 = {
    "maxItems": 10,
    "searchTerms": ["iphone 17"],
}

# Run the Actor and wait for it to finish
run = client.actor("normdata/billiger-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 '{
  "maxItems": 10,
  "searchTerms": [
    "iphone 17"
  ]
}' |
apify call normdata/billiger-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,normdata/billiger-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/kB6NdkJzN9SHfDf3g/builds/ajtoqWKOxLR7RGx7r/openapi.json
