# Kleinanzeigen.de Scraper (`trev0n/kleinanzeigen-scraper`) Actor

Scrape kleinanzeigen.de ads by keyword, category and location. Price, seller-type and offer-type filters, radius search, full ad pages with attributes, seller info and GPS, and incremental monitoring that emits only new or changed ads on scheduled runs.

- **URL**: https://apify.com/trev0n/kleinanzeigen-scraper.md
- **Developed by:** [Paweł](https://apify.com/trev0n) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 results

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?

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.de Scraper

🎯 **Get every ad from Germany's biggest classifieds site — cars, bikes, flats, electronics, furniture and more — as clean, ready-to-use data.**

Search kleinanzeigen.de by keyword, category and location, filter by price, seller type and offer type, and get each ad's title, price, place, date, photos, seller type and category. Switch on full details for the complete description, every attribute (mileage, first registration, living area, rooms, warm rent, deposit, condition…), equipment, GPS coordinates and seller profile. Monitoring mode then delivers **only new and changed ads** on every scheduled run.

### 🚀 What Does It Do?

This scraper automatically searches kleinanzeigen.de and collects **structured, ready-to-use data** for every ad it finds. No manual browsing needed — just set your filters and hit Start.

💡 **Two modes of operation:**

1. **🔍 Discovery Mode** — enter search terms, pick a category and a city (with a radius), set a price range and seller type, and the scraper pages through all results for you.
2. **📋 Direct URL Mode** — paste any kleinanzeigen.de search page (every filter you set on the site is kept) or individual ad pages.

🔁 **Monitoring mode** remembers what earlier runs saw. Schedule it hourly or daily and get only the **new ads, price drops and edits** — perfect for deal hunting, and you only pay for what's new.

### 👥 Who Is This For?

| 🏢 Use Case                           | 💬 How It Helps                                                                                          |
| ------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| 🚗 **Car dealers & traders**          | Spot underpriced cars the minute they're listed, with mileage and first registration on every ad         |
| 🏠 **Real-estate investors & agents** | Track rents, living areas and deposits across cities and districts to price your own listings            |
| 🛍️ **Resellers & flippers**           | Get alerted to new bargains in your niche (bikes, consoles, designer furniture) before anyone else calls |
| 📊 **Market researchers**             | Build price indices for used goods by category, region and condition                                     |
| 🏪 **Retailers & brands**             | See which of your products are resold second-hand, at what price and where                               |
| 🤖 **Data & AI teams**                | Feed a steady, structured stream of German classifieds into your models and dashboards                   |

### ✨ Features

- 🔍 **Keyword, category & location search** — every one of the 160+ categories, and 5 500+ cities, districts and states by name
- 📏 **Radius search** — from +5 km to +200 km around any place, with the exact distance on every ad
- 💶 **Price, seller & offer filters** — price range, private or commercial sellers, offers or wanted ads, "Direkt kaufen" and shipping
- ↕️ **Sorting** — newest first, cheapest first or most expensive first
- 📑 **Full ad details** — complete description, all attributes and equipment, GPS coordinates, street (real estate), seller name, seller since and badges
- 🚗 **Vehicle data** — mileage and first registration straight from the result list
- 🏠 **Real-estate data** — living area, rooms, warm rent, service charges and deposit
- 🏪 **Commercial seller info** — shop name, shop page and business phone number
- 🔁 **Monitoring mode** — only NEW, UPDATED and REAPPEARED ads, with repost detection
- 🔔 **Instant alerts** — Telegram, Discord, Slack or any webhook when new ads appear
- 🙈 **Skip paid TOP ads** — keep your results in true date order
- ⚡ **Fast & Scalable** — hundreds of ads per minute; thousands per run
- 🧹 **Deduplication** — every ad appears once, even across several searches
- 📤 **Export Anywhere** — Download results as JSON, CSV, Excel, or push to Google Sheets, Zapier, Make, or your CRM

### 🎛️ Filters & Options

| Option                                       | What It Does                                                                    |
| -------------------------------------------- | ------------------------------------------------------------------------------- |
| 🔍 **Search terms**                          | One or more search phrases, each run as its own search                          |
| 🗂️ **Category**                              | Any category or sub-category, e.g. Autos, Fahrräder, Mietwohnungen, Smartphones |
| 📍 **Location**                              | A city, district or state — "Berlin", "München", "Bayern"                       |
| 📏 **Radius**                                | Include ads up to +200 km around the location                                   |
| 💶 **Minimum / maximum price**               | Only ads inside your budget                                                     |
| ↕️ **Sort by**                               | Newest, price low to high, price high to low                                    |
| 👤 **Seller type**                           | Private sellers, commercial sellers, or both                                    |
| 🏷️ **Ad type**                               | Offers (Angebote), requests (Gesuche), or both                                  |
| 🛒 **"Direkt kaufen" only**                  | Only ads you can buy directly with buyer protection                             |
| 📦 **Shipping available only**               | Only ads the seller will ship                                                   |
| 🔢 **Max results**                           | Control how many ads to extract per run                                         |
| 📄 **Max pages per search**                  | Stop each search after a number of result pages                                 |
| 📑 **Include full ad details**               | Open every ad for its complete information                                      |
| ✂️ **Max description length**                | Shorten long descriptions                                                       |
| ✅ **Must contain / 🚫 Must not contain**    | Keep or drop ads by words in the title or description                           |
| 🙈 **Skip paid TOP ads**                     | Leave out paid placements                                                       |
| ⏱️ **Max ad age**                            | Only ads posted in the last X minutes                                           |
| 🗜️ **Compact output / 🧹 Drop empty fields** | Slimmer results for spreadsheets                                                |
| 🔁 **Monitoring mode**                       | Only new and changed ads on scheduled runs                                      |
| 🔔 **Notifications**                         | Telegram, Discord, Slack or webhook alerts                                      |
| 🔗 **Direct URLs**                           | Optionally provide specific search or ad URLs to scrape                         |

### 📦 What You Get (Output Fields)

Every ad includes:

#### 🏷️ Ad

| Field              | Example                                                                                  |
| ------------------ | ---------------------------------------------------------------------------------------- |
| adId               | `3527315590`                                                                             |
| title              | `VW Golf 7 1.6 TDI BlueMotion, sehr gepflegt`                                            |
| url                | `https://www.kleinanzeigen.de/s-anzeige/vw-golf-7-1-6tdi-bluemotion/3527312922-216-3408` |
| price              | `6490`                                                                                   |
| priceType          | `NEGOTIABLE`                                                                             |
| priceText          | `6.490 € VB`                                                                             |
| oldPrice           | `6990`                                                                                   |
| descriptionSnippet | `Verkaufe meinen gepflegten Golf 7 mit Parkpilot, Scheckheft…`                           |
| postedAt           | `2026-09-30T12:15:00.000Z`                                                               |
| isTopAd            | `false`                                                                                  |
| imageUrl           | `https://img.kleinanzeigen.de/api/v1/prod-ads/images/…?rule=$_59.JPG`                    |
| imageCount         | `19`                                                                                     |

#### 📍 Location

| Field                | Example            |
| -------------------- | ------------------ |
| postalCode           | `12105`            |
| city                 | `Tempelhof`        |
| state                | `Berlin`           |
| distanceKm           | `4.2`              |
| latitude / longitude | `52.4462, 13.3861` |
| street               | `Leibnizstraße`    |

#### 🚗🏠 Vehicle & Real-Estate Data

| Field             | Example                                                                       |
| ----------------- | ----------------------------------------------------------------------------- |
| mileageKm         | `189900`                                                                      |
| firstRegistration | `05/2015`                                                                     |
| livingAreaM2      | `60.49`                                                                       |
| rooms             | `2`                                                                           |
| attributes        | `{ "Kraftstoffart": "Diesel", "Getriebe": "Manuell", "HU bis": "März 2027" }` |
| attributesRaw     | `{ "km": 189900, "ez": 2015, "fuel": "diesel", "warmmiete": 697 }`            |
| features          | `["Klimaanlage", "Einparkhilfe", "Tempomat"]`                                 |

#### 👤 Seller

| Field             | Example                                    |
| ----------------- | ------------------------------------------ |
| sellerType        | `PRIVATE`                                  |
| sellerName        | `Markus`                                   |
| sellerActiveSince | `14.03.2016`                               |
| sellerBadges      | `["TOP Zufriedenheit", "Sehr freundlich"]` |
| shopName          | `Autohaus Tempelhof GmbH`                  |
| phone             | `+49 30 1234567` (commercial sellers only) |

#### 🔁 Monitoring

| Field       | Example                    |
| ----------- | -------------------------- |
| changeType  | `NEW`                      |
| firstSeenAt | `2026-09-30T12:20:00.000Z` |
| isRepost    | `false`                    |

### 📊 Example Output

```json
{
    "adId": "3527312922",
    "url": "https://www.kleinanzeigen.de/s-anzeige/vw-golf-7-1-6tdi-bluemotion/3527312922-216-3408",
    "title": "VW Golf 7 1.6 TDI BlueMotion, sehr gepflegt",
    "price": 6490,
    "priceType": "NEGOTIABLE",
    "priceText": "6.490 € VB",
    "oldPrice": 6990,
    "currency": "EUR",
    "descriptionSnippet": "Verkaufe meinen gepflegten Golf 7 mit Parkpilot, Scheckheft gepflegt...",
    "postalCode": "12105",
    "city": "Tempelhof",
    "district": null,
    "locationText": "12105 Tempelhof",
    "distanceKm": null,
    "categoryId": "216",
    "locationId": "3408",
    "postedAt": "2026-09-30T12:15:00.000Z",
    "postedText": "Heute, 14:15",
    "shippingAvailable": false,
    "directBuy": false,
    "mileageKm": 189900,
    "firstRegistration": "05/2015",
    "rooms": null,
    "livingAreaM2": null,
    "tags": ["189.900 km", "EZ 05/2015"],
    "isTopAd": false,
    "isHighlighted": false,
    "isCommercial": false,
    "sellerType": "PRIVATE",
    "sellerId": "118223344",
    "shopName": null,
    "shopUrl": null,
    "imageUrl": "https://img.kleinanzeigen.de/api/v1/prod-ads/images/3a/3a1f0c2e-9b1d-4f7e-a1c3-5d2e8f9a0b11?rule=$_59.JPG",
    "images": [
        "https://img.kleinanzeigen.de/api/v1/prod-ads/images/3a/3a1f0c2e-9b1d-4f7e-a1c3-5d2e8f9a0b11?rule=$_59.JPG"
    ],
    "imageCount": 19,
    "hasVideo": false,
    "hasVirtualTour": false,
    "searchQuery": "golf 7",
    "searchUrl": "https://www.kleinanzeigen.de/s-autos/berlin/golf-7/k0c216l3331",
    "detailFetched": true,
    "description": "Verkaufe meinen gepflegten Golf 7 mit Parkpilot.\nScheckheft gepflegt, 2 Hand, Nichtraucher.",
    "state": "Berlin",
    "latitude": 52.4462,
    "longitude": 13.3861,
    "street": null,
    "offerType": "OFFERED",
    "categoryName": "Autos",
    "categoryPath": ["Auto, Rad & Boot", "Autos"],
    "attributes": {
        "Marke": "Volkswagen",
        "Modell": "Golf",
        "Kilometerstand": "189.900 km",
        "Kraftstoffart": "Diesel"
    },
    "attributesRaw": { "marke": "volkswagen", "model": "golf", "km": 189900, "ez": 2015, "fuel": "diesel" },
    "features": ["Klimaanlage", "Einparkhilfe", "Tempomat"],
    "sellerName": "Markus",
    "sellerActiveSince": "14.03.2016",
    "sellerBadges": ["TOP Zufriedenheit", "Sehr freundlich"],
    "phone": null,
    "contentHash": "4f1a9c0d2b7e6a53",
    "scrapedAt": "2026-09-30T12:20:00.000Z"
}
```

### 📋 Dataset Views

The Apify Console gives you **5 ready-made table views** to quickly browse your results:

| View                      | What It Shows                                              |
| ------------------------- | ---------------------------------------------------------- |
| 📊 **Overview**           | Photo, title, price, place, date, seller type and link     |
| 🚗 **Vehicles**           | Price, mileage, first registration, place and seller type  |
| 🏠 **Real estate**        | Price, living area, rooms, place and agency                |
| 🔁 **Monitoring changes** | What's new, updated or back — with first and last seen     |
| 📋 **Full Details**       | Description, attributes, equipment, seller profile and GPS |

### ❓ FAQ

**🤔 How many ads can I get from one search?**
kleinanzeigen.de shows up to 1 250 ads per search. For more, split your search by price range, category or city — you can run many searches in one go, and duplicates are removed automatically.

**🤔 What does monitoring mode do?**
It remembers every ad from earlier runs. Each new run delivers only ads that are new, whose price or text changed, or that came back online — so a daily run of "iPhone in Hamburg under 400 €" gives you just today's fresh offers.

**🤔 Can I get alerts on my phone?**
Yes — add a Telegram bot, a Discord or Slack webhook, or any webhook URL, and every run with new ads sends you a short message with titles, prices and links.

**🤔 Do I need the full details option?**
Not always. The result list already gives title, price, place, date, photos, seller type — and mileage for cars, living area and rooms for flats. Turn on full details when you need the complete description, all attributes, equipment, GPS and the seller profile.

**🤔 Can I paste a search I set up on kleinanzeigen.de?**
Yes — copy the address of any result page, with all your filters, and paste it into Start URLs.

**🤔 Can I export the data?**
Yes — JSON, CSV, Excel, XML, HTML, RSS. You can also push data directly to Google Sheets, Zapier, Make, or any webhook/API endpoint.

**🤔 How often should I run this?**
For fresh data, run daily or weekly. You can schedule automatic runs on Apify with just a few clicks.

**🤔 Does it work with proxies?**
Yes — it works without a proxy in most runs, and automatically switches to residential proxies if the site starts refusing requests. The scraper works with Apify's built-in proxy service.

### 🛠️ Need Custom Filters or Features?

**I'm happy to customize this scraper for your specific needs!** 🤝

Whether you need:

- 🎯 Additional filters (car make and model, fuel type, first registration year, number of rooms, living area, condition)
- 📊 Extra data fields or custom output formats
- 🔄 Integration with your CRM, Google Sheets, or database
- ⏰ Scheduled scraping with automatic deduplication
- 🌐 Scraping from other classifieds platforms alongside kleinanzeigen.de (willhaben.at, mobile.de, ImmoScout24, OLX)

👉 **Don't hesitate to reach out via private message** — I respond quickly and I'm always open to building exactly what you need. No request is too small or too specific!

### ⚖️ Legal & Ethical Use

This scraper collects **only publicly available information** from kleinanzeigen.de. It does not log in, does not read private messages or private sellers' phone numbers, and does not open seller-profile pages. Please use the data responsibly and in compliance with applicable laws (including GDPR) and platform terms of service.

# Actor input Schema

## `searchQueries` (type: `array`):

What to search for, e.g. "e-bike" or "iphone 15". Each term is a separate search; results are deduplicated. Leave empty to list everything in the chosen category and/or location.

## `category` (type: `string`):

Limit the search to one category or sub-category.

## `location` (type: `string`):

City, district or state, e.g. "Berlin", "München", "Frankfurt am Main", "Bayern". Add the state to disambiguate ("Neustadt, Bayern"). A numeric kleinanzeigen location id also works. Leave empty for all of Germany.

## `radiusKm` (type: `string`):

Include ads around the location. Needs a location.

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

Paste kleinanzeigen.de search result pages (any filters you set on the site are kept) or individual ad pages.

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

0 = no minimum.

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

0 = no maximum.

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

Order of the results.

## `posterType` (type: `string`):

Private sellers, commercial sellers or both.

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

Offers (Angebote), requests (Gesuche) or both.

## `buyNowOnly` (type: `boolean`):

Only ads that can be bought directly with buyer protection.

## `shippingOnly` (type: `boolean`):

Only ads whose seller offers shipping.

## `maxResults` (type: `integer`):

Maximum number of ads per run across all searches. 0 = unlimited (kleinanzeigen.de shows at most 1 250 ads per search — narrow by price, category or location to go further).

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

25 ads per page. 0 = no limit (the site stops at 50).

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

Open every ad page for the full description, all attributes (mileage, rooms, rent, condition…), equipment, GPS coordinates, seller name, seller since and badges. Slower: one extra request per ad.

## `descriptionMaxLength` (type: `integer`):

Truncate full descriptions to this many characters. 0 = no limit.

## `detailConcurrency` (type: `integer`):

How many ad pages to open at the same time.

## `includeKeywords` (type: `array`):

Keep only ads whose title or description contains at least one of these words.

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

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

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

TOP ads are paid placements that repeat at the top of every page, out of date order.

## `maxAgeMinutes` (type: `integer`):

Keep only ads posted within this many minutes. 0 = any age.

## `compact` (type: `boolean`):

Only the essential fields: id, title, price, place, date, seller type, URL, image.

## `excludeEmptyFields` (type: `boolean`):

Remove fields with no value from every result.

## `incrementalMode` (type: `boolean`):

Remember what earlier runs saw and output only NEW, UPDATED (price or text changed) and REAPPEARED ads. Schedule the actor to get fresh deals only — and pay only for them.

## `stateKey` (type: `string`):

Name of the memory this monitor uses. Leave empty to derive it from the search. Use different names for different monitors.

## `emitUnchanged` (type: `boolean`):

In monitoring mode, also output ads that did not change since the last run.

## `emitExpired` (type: `boolean`):

In monitoring mode, also output ads that are no longer in the results.

## `skipReposts` (type: `boolean`):

Drop NEW ads whose content matches an ad that recently disappeared (the same item re-posted under a new id).

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

POST the new/changed ads as JSON to this URL after each run.

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

Token of your Telegram bot (from @BotFather).

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

Chat id the Telegram bot should post to.

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

Discord channel webhook URL.

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

Slack incoming webhook URL.

## `notifyOnlyChanges` (type: `boolean`):

Send a notification only when a run found new or changed ads.

## `notificationLimit` (type: `integer`):

How many ads to list in one notification.

## `includeRunSummary` (type: `boolean`):

Add the run statistics to the webhook payload.

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

kleinanzeigen.de works without a proxy in most runs.

## `residentialFallback` (type: `boolean`):

If the site refuses a request, the rest of the run continues through German residential proxies.

## Actor input object example

```json
{
  "searchQueries": [
    "fahrrad"
  ],
  "category": "",
  "radiusKm": "0",
  "minPrice": 0,
  "maxPrice": 0,
  "sort": "newest",
  "posterType": "",
  "adType": "",
  "buyNowOnly": false,
  "shippingOnly": false,
  "maxResults": 100,
  "maxPagesPerSearch": 0,
  "includeDetails": false,
  "descriptionMaxLength": 0,
  "detailConcurrency": 5,
  "excludeTopAds": false,
  "maxAgeMinutes": 0,
  "compact": false,
  "excludeEmptyFields": false,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "skipReposts": false,
  "notifyOnlyChanges": true,
  "notificationLimit": 10,
  "includeRunSummary": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "residentialFallback": true
}
```

# Actor output Schema

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

No description

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

No description

## `runSummary` (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 = {
    "searchQueries": [
        "fahrrad"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("trev0n/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 = {
    "searchQueries": ["fahrrad"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("trev0n/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 '{
  "searchQueries": [
    "fahrrad"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call trev0n/kleinanzeigen-scraper --silent --output-dataset

```

## MCP server setup

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