# Kleinanzeigen Scraper: Deal Finder & Price-Drop Alerts (`euroscrape/kleinanzeigen-scraper`) Actor

Scrape Kleinanzeigen.de ads with a 0–100 deal score vs. market price, monitor mode for new ads & price drops, Telegram/Discord/Slack alerts, view counts, scam flags and full seller details.

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

## Pricing

from $1.40 / 1,000 ads

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

## Kleinanzeigen Scraper: Deal Finder, Price-Drop Alerts & Full Ad Details

Scrape **Kleinanzeigen.de** (formerly eBay Kleinanzeigen), Germany's #1 classifieds site. Unlike a plain scraper, this one also **tells you which ads are good deals**, **watches your searches for new ads and price drops**, and can **alert you instantly on Telegram, Discord or Slack**.

Search by keyword, city, radius, price and seller type, or paste any Kleinanzeigen search URL. You get clean JSON, CSV or Excel output with numeric prices, exact timestamps, condition, category, GPS coordinates, shipping, view counts and seller profiles.

**You only pay for ads you receive.** There are no monthly fees, and failed pages cost nothing.

### ✨ What makes it different

| | This Actor |
|---|---|
| 📊 **Deal score for every ad** | Each price is compared with the median of the most similar ads (matched on model, storage, variant…), plus Kleinanzeigen's own "similar ads" when the page shows them. You get `marketMedianPrice`, `priceVsMarketPct` and a 0–100 `dealScore`. |
| 🔔 **Monitor mode with price drops** | Name a search and schedule it. Each run returns only **new ads** and **ads whose price dropped**, with the old price and the % drop. |
| 📲 **Built-in alerts** | Telegram (with photo), Discord, Slack or any webhook (Make, Zapier, n8n). No extra integration needed. |
| 👀 **View counts** | Views and views per day for every detailed ad, so you can see how hot a listing is. |
| ⚠️ **Scam signals** | `riskFlags` such as price far below market, brand-new account, no photos, or suspicious wording (PayPal Friends, Western Union, WhatsApp-only…). |
| 🧭 **Multi-search** | Several keywords × several cities in one run, with automatic de-duplication and balanced results. |
| 🧾 **Rich details** | Exact posting time, condition (normalized to English), all attributes, category IDs, GPS, shipping cost, buy-now, "offer possible", secure payment, seller type, member-since date, ads online and rating badges. |
| 🛡️ **Reliable** | A fast HTTP scraper with automatic proxy escalation. It handles both page layouts Kleinanzeigen currently serves. |

### 🎯 Use cases

- **Reselling and flipping**: get pinged within minutes when an underpriced iPhone, e-bike or PS5 appears near you.
- **Price research**: see what used products really cost in each region, with sold similar ads when Kleinanzeigen shows them.
- **Dealers and shops**: track competitors' listings and prices, and spot commercial sellers.
- **Market data and AI agents**: the clean, typed output is ready for spreadsheets, BI tools or LLM agents via the Apify MCP server.

### 🚀 Quick start

**Find deals on an iPhone 13 around Berlin and Munich:**

```json
{
  "keywords": ["iphone 13"],
  "locations": ["Berlin", "München"],
  "radiusKm": 20,
  "excludeKeywords": ["defekt", "tausch", "suche"],
  "minDealScore": 65,
  "maxItems": 50
}
```

**Get a Telegram alert for every new e-bike under €800 in Hamburg (schedule it every 15 min):**

```json
{
  "keywords": ["e-bike"],
  "locations": ["Hamburg"],
  "radiusKm": 30,
  "maxPrice": 800,
  "monitorName": "ebike-hamburg",
  "telegramBotToken": "123456:ABC...",
  "telegramChatId": "123456789"
}
```

**Full details for any search URL:**

```json
{
  "searchUrls": [{ "url": "https://www.kleinanzeigen.de/s-fahrraeder/k0c217" }],
  "includeDetails": true,
  "maxItems": 200
}
```

### 📦 Output example (a real ad, with `includeDetails`)

```json
{
  "id": "3526178105",
  "url": "https://www.kleinanzeigen.de/s-anzeige/iphone-13-mini-blau-128gb/3526178105-173-6182",
  "title": "Iphone 13 mini blau 128gb",
  "price": 150,
  "priceType": "FIXED",
  "priceText": "150 €",
  "currency": "EUR",
  "postedAt": "2026-09-29T05:53:43.000Z",
  "location": "85640 Kr. München - Putzbrunn",
  "postalCode": "85640",
  "state": "Bayern",
  "latitude": 48.079455204269486,
  "longitude": 11.707305908203125,
  "category": "Smartphones",
  "categoryId": 173,
  "condition": "good",
  "attributes": {
    "Art": "Apple",
    "Modell": "iPhone 13 mini",
    "Farbe": "Blau",
    "Gerät & Zubehör": "Gerät",
    "Zustand": "Gut",
    "Versand": "Versand möglich"
  },
  "shippingAvailable": true,
  "shippingText": "+ Versand ab 6,19 €",
  "buyNowAvailable": true,
  "offerPossible": true,
  "images": [
    "https://img.kleinanzeigen.de/api/v1/prod-ads/images/bb/bb77743f-ae9a-4ac4-b37b-5fcf535a3f38?rule=$_59.JPG"
  ],
  "views": 47,
  "viewsPerDay": 47,
  "marketMedianPrice": 225,
  "marketConfidence": "high",
  "marketSource": "search_comparables",
  "priceVsMarketPct": -33,
  "dealScore": 83,
  "comparableAds": [
    {
      "id": "3526076524",
      "title": "iPhone 13 mini 128 GB midnight blue",
      "price": 225,
      "url": "https://www.kleinanzeigen.de/s-anzeige/iphone-13-mini-128-gb-midnight-blue/3526076524-173-6444"
    },
    {
      "id": "3524663960",
      "title": "iPhone 13 mini 128gb Midnight",
      "price": 250,
      "url": "https://www.kleinanzeigen.de/s-anzeige/iphone-13-mini-128gb-midnight/3524663960-173-16395"
    }
  ],
  "similarAdsMedianPrice": 160,
  "similarAdsSoldCount": 0,
  "riskFlags": [],
  "seller": {
    "id": "…",
    "name": "…",
    "type": "private",
    "activeSince": "2014-06-17",
    "adsOnline": null,
    "badges": [
      "TOP Zufriedenheit",
      "Sehr freundlich",
      "Besonders zuverlässig"
    ]
  },
  "changeType": null,
  "search": {
    "keyword": "iphone 13",
    "location": "München"
  }
}
```

Without `includeDetails` you still get the id, url, title, numeric price, price type, location, postal code, posting time, shipping, buy-now, image, description snippet and the full deal analysis.

In monitor mode, a price drop looks like this: `"changeType": "price_drop", "previousPrice": 520, "priceDropPct": 13`.

### 📊 How the deal score works

1. We collect the ads from your search, pooled across all your cities for the same keyword.
2. For each ad, we find the most similar listings. We compare titles with TF-IDF weighting, so rare, distinguishing words like "Pro", "Max" or "256GB" count far more than words every ad shares ("iPhone", "13").
3. We take the similarity-weighted median of their prices. If comparables are too scattered (for example accessories mixed with devices), we give **no estimate** rather than a wrong one.
4. When Kleinanzeigen shows its own "similar ads" on the page, we use them as a second reference.

On a test set of 1,151 real ads, `high`-confidence estimates were within **~13%** of the listed price (median error). A naive "median of the whole search" was off by ~60%. Treat `medium` estimates (~19% error) as a hint.

### 💰 Pricing

Pay per event:

| Event | Price |
|---|---|
| Ad from search results (incl. deal analysis) | **$2.00 / 1,000 ads** |
| Ad with full details (incl. views, seller, deal analysis) | **$4.00 / 1,000 ads** |
| Run start (once per run) | **$0.003** |

Alerts, monitoring and deal analysis are included at no extra cost. Set a max budget per run and the Actor stops cleanly when it's reached.

### 💡 Tips

- **Deal hunting**: use `minDealScore: 65` together with `excludeKeywords` such as "defekt", "kaputt", "tausch" or "suche".
- **Monitoring**: the first run of a new `monitorName` records everything currently online as the baseline. From the second run on, you only get what's new or cheaper. Schedule it in Apify (for example every 10–30 minutes).
- **Big searches**: Kleinanzeigen shows about 25 ads per page and at most ~50 pages per search. Split by city or price range to go further.
- **Telegram setup**: create a bot with @BotFather to get the token, send it one message, then get your chat ID from @userinfobot.

### 🤖 For AI agents

- Minimal input: `{ "keywords": ["iphone 13"], "maxItems": 20 }`.
- Every price is a number (`price`), with the type in `priceType` (`FIXED`, `NEGOTIABLE`, `GIVE_AWAY`, `ON_REQUEST`).
- `dealScore` runs from 0 to 100; 50 means priced at market.
- `postedAt` is an ISO-8601 UTC timestamp.
- Use `id` as the unique key.

### ⚖️ Legal

This Actor only accesses publicly visible Kleinanzeigen pages, with no login. It is not affiliated with Kleinanzeigen GmbH. You are responsible for using the data in line with the GDPR and Kleinanzeigen's terms. In particular, don't store or re-publish personal data (seller names) you don't need.

### ⭐ Your feedback

If this Actor saves you time, a short review on Apify Store helps other users find it. Missing a field, a country or a filter? Say it in your review: the most requested features are added first.

### 🔗 More from EuroScrape

- [Vinted Scraper: 26 Countries, Deals, Alerts & Seller Data](https://apify.com/euroscrape/vinted-scraper): search Vinted across 26 countries, prices with buyer fees, seller ratings, cheapest-country comparison and instant alerts on new listings.
- [EU Second-Hand Marketplaces Scraper: Vinted, OLX & More](https://apify.com/euroscrape/eu-marketplace-deals): one search on the top second-hand marketplace of 18 European countries, prices in €, cheapest country and resale margin.
- [Website Tech Stack Detector: 280+ Technologies, Leads & Signals](https://apify.com/euroscrape/website-intelligence): technologies, company identity, contacts and sales signals for any website.
- [French Companies Scraper (SIRENE)](https://apify.com/euroscrape/france-companies): All French companies by activity, area, size and revenue, with directors, finances and SIREN-verified websites, emails and phones.
- [UK Companies House Scraper](https://apify.com/euroscrape/uk-companies): UK companies by SIC code, location and incorporation date, with directors, filing dates, websites, emails and phones.
- [Impressum & Legal Notice Scraper (EU)](https://apify.com/euroscrape/company-identity): Turn any company website into a verified identity: legal name, registry numbers, VAT IDs, directors and contacts, across Europe.
- [EU Public Tenders Scraper: TED, BOAMP & Awards](https://apify.com/euroscrape/eu-public-tenders): open tenders and contract awards from all of Europe (TED) and France (BOAMP, DECP), with winners per lot, values in € and daily alerts.
- [Google Hotels Scraper: Prices from Every Booking Site](https://apify.com/euroscrape/google-hotels-prices): hotel prices for any destination and dates, with the price on every booking site, rate parity, price calendars and alerts.
- [App Store Reviews Scraper + Google Play Reviews](https://apify.com/euroscrape/app-reviews): reviews from both stores in 58 countries, rating by version and country, alerts on new negative reviews.
- [Google Flights Scraper: Cheapest Dates, Prices & Price History](https://apify.com/euroscrape/google-flights-prices): flight prices for any route and dates, cheapest day to fly, typical price range, CO2 and price-drop alerts.
- [EU VAT Number Validator (VIES): Bulk Check, Proof & Alerts](https://apify.com/euroscrape/vat-validator): validate VAT numbers in bulk against the EU's official registry, with consultation proof for tax audits and alerts when a customer's number becomes invalid.
- [France Real Estate Sold Prices (DVF): €/m², Sales & Trends](https://apify.com/euroscrape/france-property-prices): every property sale registered by the French State — real prices, €/m², addresses, GPS, market trends per city and alerts on new sales.

💡 Selling to the German-speaking market? The **Impressum & Legal Notice Scraper** turns any shop or company website into legal name, HRB number, VAT ID and contacts.

# Actor input Schema

## `keywords` (type: `array`):

One or more search terms, e.g. "e-bike", "iPhone 15 Pro". Each keyword is searched in every location.

## `locations` (type: `array`):

Cities or postal codes, e.g. "Berlin", "80331". Leave empty for all of Germany.

## `radiusKm` (type: `integer`):

Search radius around each location (Kleinanzeigen supports 5, 10, 20, 30, 50, 100, 150 or 200 km; other values are rounded).

## `minPrice` (type: `integer`):

Optional.

## `maxPrice` (type: `integer`):

Optional.

## `searchUrls` (type: `array`):

Any Kleinanzeigen search or category URL, with your filters already applied on the site. Can be combined with keywords.

## `sellerType` (type: `string`):

Applies to keyword searches.

## `adType` (type: `string`):

Applies to keyword searches.

## `excludeKeywords` (type: `array`):

Drop ads whose title/description contains any of these words, e.g. "defekt", "tausch", "suche".

## `onlyWithShipping` (type: `boolean`):

Keep only ads marked "Versand möglich".

## `excludeTopAds` (type: `boolean`):

Drop promoted ads that are pinned at the top regardless of date.

## `maxAgeHours` (type: `integer`):

Keep only ads posted in the last N hours, e.g. 24.

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

You only pay for ads returned.

## `maxPagesPerSearch` (type: `integer`):

\~25 ads per page.

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

Open every ad: full description, all images, condition, category, GPS, shipping, buy-now, view count and seller profile (type, member since, ads online, badges). Billed as a detailed ad.

## `includeViews` (type: `boolean`):

With full details: number of views and views per day (how hot an ad is).

## `dealAnalysis` (type: `boolean`):

Compare every price with the market median of similar ads in the same search: marketMedianPrice, priceVsMarketPct and a 0–100 dealScore (100 = far below market). Free.

## `minDealScore` (type: `integer`):

E.g. 65 keeps ads priced ~15% or more below the market.

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

Name this search and schedule the run: every run then returns only ads that are NEW or whose PRICE DROPPED since the previous run with the same name.

## `alertOn` (type: `string`):

Which changes trigger an alert.

## `telegramBotToken` (type: `string`):

Get instant alerts with photo, price and deal score. Create a bot with @BotFather.

## `telegramChatId` (type: `string`):

Your chat or channel ID (message @userinfobot to get yours).

## `discordWebhookUrl` (type: `string`):

Channel settings → Integrations → Webhooks.

## `slackWebhookUrl` (type: `string`):

Incoming webhook URL.

## `webhookUrl` (type: `string`):

Receives one JSON POST per run with all new items (Make, Zapier, n8n…).

## `maxNotifications` (type: `integer`):

Extra items are summarized in one message.

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

Default: fast datacenter proxy with automatic fallback to German residential IPs only when a request is blocked. You can pick your own proxy instead.

## Actor input object example

```json
{
  "keywords": [
    "iphone 15"
  ],
  "radiusKm": 0,
  "sellerType": "any",
  "adType": "offered",
  "onlyWithShipping": false,
  "excludeTopAds": false,
  "maxItems": 30,
  "maxPagesPerSearch": 10,
  "includeDetails": false,
  "includeViews": true,
  "dealAnalysis": true,
  "alertOn": "new_and_price_drops",
  "maxNotifications": 30,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Ads with price, deal score and market estimate.

## `details` (type: `string`):

Condition, category, views, shipping and seller (with includeDetails).

## `runSummary` (type: `string`):

Counters for this run (items found, output, errors).

# 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 = {
    "keywords": [
        "iphone 15"
    ],
    "maxItems": 30,
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("euroscrape/kleinanzeigen-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 = {
    "keywords": ["iphone 15"],
    "maxItems": 30,
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("euroscrape/kleinanzeigen-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 '{
  "keywords": [
    "iphone 15"
  ],
  "maxItems": 30,
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call euroscrape/kleinanzeigen-scraper --silent --output-dataset

```

## MCP server setup

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