# Kleinanzeigen Scraper - Germany Classifieds Listings & Prices (`rjmacarthy/kleinanzeigen-scraper`) Actor

Scrape kleinanzeigen.de (formerly eBay Kleinanzeigen) by keyword, city and category: parsed prices and price type (VB/Festpreis/zu verschenken), ISO dates, location, images, optional full ad details and an only-new mode for deal alerts. No start fee, privacy-safe.

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

## Pricing

from $1.50 / 1,000 listing scrapeds

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 Scraper: Germany Classifieds Listings & Prices

**Kleinanzeigen Scraper** extracts listings from **kleinanzeigen.de** (formerly eBay Kleinanzeigen), Germany's biggest classifieds site, in **every category**: bikes, phones, furniture, cars, flats and more. Search by keyword, **city or state** and category, or paste a search URL from your browser. Each listing comes with a **numeric price and price type** (Festpreis, VB, zu verschenken), postcode and city, **ISO dates** (with "Heute" and "Gestern" resolved), images, shipping and top-ad flags. Turn on **Fetch ad details** for the full description, attributes (Art, Zustand, ...), every image and the seller type. Turn on **Only new listings** and schedule it for deal alerts.

Why this one? There is **no start fee**: you pay only per listing. It covers all categories (not just real estate), parses prices and dates into clean fields, and lets you choose whether to pay for details. It is **privacy-safe by design**: private sellers are never identified. You get no name, no user ID, no profile link and no phone number, and phone numbers or e-mail addresses that private sellers typed into their ads are removed. For commercial sellers you get only the business name and shop link.

### What data can you get?

| Field | Example | Notes |
|---|---|---|
| `id`, `url`, `title` | 3562309491, Hercules Futura Sport E-Bike | Stable Kleinanzeigen ad ID |
| `price`, `priceType`, `priceText`, `currency` | 799, `fixed`, "799 €", EUR | `fixed` (Festpreis), `negotiable` (VB) or `free` (zu verschenken, price 0) |
| `originalPrice` | 5800 | Struck-through earlier price after a price drop |
| `descriptionSnippet` | Verkaufe mein ca. fünf Jahre altes ... | The preview text from the results page |
| `zip`, `city`, `state`, `locationId` | 51143, Porz, Nordrhein-Westfalen | `state` with details |
| `category`, `categoryId` | Fahrräder & Zubehör, 217 | For every listing, even in keyword searches |
| `postedAt`, `postedAtText` | 2026-11-05T13:15:00+01:00, "Heute, 13:15" | ISO 8601 in German time |
| `imageUrl`, `imageCount` | large image URL, 11 | |
| `isTopAd`, `isPro`, `adType` | false, false, `offer` | Paid top placement, PRO shop, offer or `wanted` (Gesuch) |
| `shippingAvailable`, `buyNowAvailable` | true, false | "Versand möglich", "Direkt kaufen" |
| `sellerType`, `sellerName`, `sellerShopUrl` | `commercial`, Geobikes GmbH | Business name **only for commercial sellers**. Private sellers: always null |
| **With details:** `description`, `attributes`, `features`, `images` | {"Art": "Herren", "Zustand": "Sehr Gut"} | Full text and every image |
| `searchQuery`, `searchUrl`, `scrapedAt` | | Where and when each listing was found |

Download the results as JSON, CSV, Excel or HTML, or read them through the API.

### Use cases

- **Reselling and deal alerts:** schedule "iphone 15" in Hamburg every 15 minutes with **Only new listings** and push new ads to Telegram, Slack or e-mail.
- **Price research:** collect asking prices and VB/Festpreis splits for a model across Germany or one city.
- **Rental market monitoring:** track new flats for rent (Mietwohnungen) in München or Berlin with prices and districts.
- **Dealer and market analysis:** see which shops (commercial sellers) list what, at what price, in which category.
- **Stock sourcing:** find second-hand stock (bikes, furniture, electronics) for a shop to review, with no personal data involved.

### How to use it

1. Click **Try for free** or **Start**.
2. Type one or more **Search keywords** (e.g. `fahrrad`), a **Location** (city or state, e.g. `Berlin`) and, if you like, a **Category**. You can also leave keywords empty to browse a whole category in a city. Or paste search URLs from your browser into **Start URLs**.
3. Set **Max listings per search** (default 100).
4. Optional: **Fetch ad details**, a **price range** and **Only new listings**.
5. Click **Start**.

#### Example: bikes in Berlin

```json
{
    "searchQueries": ["fahrrad"],
    "location": "Berlin",
    "maxItems": 15
}
```

#### Example: flats for rent in Munich (category browse, no keyword)

```json
{
    "category": "203",
    "location": "München",
    "maxItems": 100
}
```

#### Example: e-bikes in Cologne between 500 and 2,000 € with full details

```json
{
    "searchQueries": ["e-bike"],
    "location": "Köln",
    "priceMin": 500,
    "priceMax": 2000,
    "fetchDetails": true,
    "maxItems": 50
}
```

#### Example: deal alert (schedule it)

```json
{
    "searchQueries": ["iphone 15", "iphone 15 pro"],
    "location": "Hamburg",
    "onlyNew": true,
    "stateKey": "iphone-hamburg",
    "maxItems": 50
}
```

### Output example

A real listing from a run (shortened), from a private seller with **Fetch ad details** on:

```json
{
  "id": "3562309491",
  "url": "https://www.kleinanzeigen.de/s-anzeige/hercules-futura-sport-e-bike-bosch-cx-85-nm-fahrrad-500-wh/3562309491-217-963",
  "title": "Hercules Futura Sport E-Bike – Bosch CX 85 Nm – Fahrrad 500 Wh",
  "price": 799,
  "priceType": "fixed",
  "priceText": "799 €",
  "originalPrice": null,
  "currency": "EUR",
  "descriptionSnippet": "Verkaufe mein ca. fünf Jahre altes, sehr gepflegtes Hercules E-Bike. Neupreis ca. 3.000 €,...",
  "zip": "51143",
  "city": "Porz",
  "state": "Nordrhein-Westfalen",
  "locationId": 963,
  "categoryId": 217,
  "category": "Fahrräder & Zubehör",
  "postedAt": "2026-11-05T13:15:00+01:00",
  "postedAtText": "Heute, 13:15",
  "imageUrl": "https://img.kleinanzeigen.de/api/v1/prod-ads/images/0b/0be5e27f-4024-47a4-a0d2-e56e984ee06e?rule=$_59.AUTO",
  "imageCount": 11,
  "isTopAd": false,
  "isPro": false,
  "adType": "offer",
  "shippingAvailable": false,
  "buyNowAvailable": false,
  "sellerType": "private",
  "sellerName": null,
  "sellerShopUrl": null,
  "detailsFetched": true,
  "description": "Verkaufe mein ca. fünf Jahre altes, sehr gepflegtes Hercules E-Bike. Neupreis ca. 3.000 €, Originalrechnung vorhanden. ...",
  "attributes": { "Art": "Herren", "Typ": "Elektrofahrräder", "Zustand": "Sehr Gut" },
  "features": [],
  "images": ["https://img.kleinanzeigen.de/api/v1/prod-ads/images/0b/0be5e27f-4024-47a4-a0d2-e56e984ee06e?rule=$_59.AUTO", "..."],
  "searchQuery": "e-bike",
  "searchUrl": "https://www.kleinanzeigen.de/s-koeln/e-bike/k0l945",
  "scrapedAt": "2026-11-05T12:28:20.854Z"
}
```

### How much does it cost?

Pay per event, **no start fee**:

| Event | Price | When |
|---|---|---|
| `listing` | **$0.0015** | Each listing saved to the dataset |
| `listing-details` | **$0.001** | Each listing whose ad page was read (only with **Fetch ad details**) |

- **1,000 listings ≈ $1.50.** With details: **1,000 listings ≈ $2.50.**
- The prefilled example (15 bikes in Berlin) costs about **$0.02**.
- In **Only new listings** mode you pay only for new listings. Listings you have already seen are free.
- Set **Maximum cost per run** in the run options: the Actor stops cleanly when the budget is reached.

### Tips and limits

- **Max 50 pages per search.** Kleinanzeigen itself shows at most 50 result pages (about 1,250 listings) per search. For more, split by city or category.
- **Results are newest first**, the site's default order. Other sort orders, the site's price filter, radius search and the private/commercial seller filter are **disallowed by kleinanzeigen.de's robots.txt**, and this Actor respects robots.txt. So:
  - **Price range** is applied to the results after scraping. A narrow range may read more pages, but you only pay for listings that match. Listings with no price (only "VB") are skipped when a price filter is set.
  - **No radius or postcode search.** Use the city, district or state name instead (`Berlin`, `Köln`, `Bayern`, or `Fürth, Bayern` for towns that exist twice). Pasted start URLs that contain a radius, price, sort or seller filter are skipped with a warning.
- **Locations:** all 16 states and about 5,700 cities and districts are built in. A raw location ID (`l3331`) also works.
- **Top ads** (paid placements, `isTopAd: true`) appear on top of every page; each is output only once per run.
- **Seller type** is known for every listing with details. Without details only PRO shops are marked `commercial`; other listings have `sellerType: null`.
- **View counts** are not included: the site loads them with a separate request that its robots.txt disallows.
- With **Fetch ad details**, the Actor reads about one ad page per second, so 1,000 detailed listings take about 15–20 minutes. Listings without details are fast (about 25 per second).
- **Only new listings:** the first run is the baseline (it outputs up to your max and remembers every listing on the pages it read). Later runs output only listings that are newer. Use a different **State key** per alert.

### FAQ

**Is it legal to scrape Kleinanzeigen?**
This Actor reads only public pages that anyone can open without logging in. It follows the site's robots.txt and paces its requests. It is built not to collect personal data: private sellers are never identified, and contact details in private ads are removed. You are responsible for how you use the data, including GDPR and the site's terms. If in doubt, ask a lawyer.

**Why is there no seller name for most listings?**
Most sellers on Kleinanzeigen are private individuals. Their names, user IDs, profile links and phone numbers are personal data, so the Actor never outputs them. You get the business name only for commercial sellers (shops and dealers).

**Do I need a proxy?**
Usually not. If kleinanzeigen.de blocks the run (HTTP 403/429), enable **Apify Proxy** (automatic/datacenter). **Residential proxies are not supported.** If you pick the RESIDENTIAL group, the Actor uses datacenter proxy instead.

**Can I scrape a search I set up in my browser?**
Yes. Paste the URL (starting with `https://www.kleinanzeigen.de/s-`) into **Start URLs**. Category and attribute filters in the URL are kept. URLs with radius, price, sort or seller filters are disallowed by robots.txt and are skipped.

**Can I get cars or real estate?**
Yes, every category works, e.g. category `216` (Autos) or `203` (Mietwohnungen). Category-specific attributes (Kilometerstand, Zimmer, Wohnfläche, ...) are in `attributes` when **Fetch ad details** is on.

**Is "VB" a price?**
"VB" (Verhandlungsbasis) means the price is negotiable. You get `priceType: "negotiable"` and the number, if one is given.

### Integrations

- **API:** run the Actor and fetch results from any language with the Apify API or the JavaScript and Python clients.
- **Make, Zapier, n8n:** use the Apify integrations to send new listings to Google Sheets, Slack, Telegram, Airtable or e-mail.
- **Webhooks:** trigger your own endpoint when a run finishes, ideal for deal alerts.
- **MCP / AI agents:** call the Actor from Claude, ChatGPT or any MCP client through the Apify MCP server, e.g. "find used e-bikes in Köln under 1,000 € on Kleinanzeigen".

### Changelog

- **0.1 (November 2026):** First release. Keyword, city/state and category search across all categories, browser search URLs, parsed price and price type, ISO dates, top-ad, shipping and PRO flags, optional ad details, only-new mode, privacy guard for private sellers.

### Ready-to-run examples

- [Find used iPhone 15 deals in Hamburg on Kleinanzeigen](https://apify.com/rjmacarthy/kleinanzeigen-scraper/examples/used-iphone-15-deals-hamburg)
- [Track flats for rent in Munich on Kleinanzeigen](https://apify.com/rjmacarthy/kleinanzeigen-scraper/examples/flats-for-rent-munich-kleinanzeigen)

### More scrapers by the same developer

- [AliExpress Scraper - Product Search, Prices, Ratings & Details](https://apify.com/rjmacarthy/aliexpress-scraper)
- [AutoScout24 Scraper - Used Car Listings & Prices (Europe)](https://apify.com/rjmacarthy/autoscout24-scraper)
- [Flipkart Scraper - Prices, Ratings & Offers from Search](https://apify.com/rjmacarthy/flipkart-scraper)
- [Property Finder Scraper - UAE Real Estate Listings (Dubai)](https://apify.com/rjmacarthy/propertyfinder-scraper)
- [Vinted Scraper: Listings, Prices & New-Item Monitor](https://apify.com/rjmacarthy/vinted-scraper)
- [Apple App Store Scraper: Apps, Search & Reviews](https://apify.com/rjmacarthy/app-store-scraper)

Browse all my Actors on [my Apify Store profile](https://apify.com/rjmacarthy).

### Support

Found a bug or need a field? Open an issue on the **Issues** tab with your input and the run ID, and we'll take a look.

# Actor input Schema

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

What you would type into Kleinanzeigen's search box, one per line, e.g. "fahrrad", "iphone 15" or "kinderwagen". Each keyword is a separate search with the location and category below. Leave empty to browse a whole category/location, or if you only use start URLs.

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

German city, district or state as written on Kleinanzeigen, e.g. "Berlin", "München", "Köln" or "Bayern". For towns that exist twice add the state ("Fürth, Bayern"); a raw location id like "l3331" also works. Empty = all of Germany. Postcodes and search radius are not supported: Kleinanzeigen's robots.txt disallows the postcode lookup and all radius URLs.

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

Optional: limit the search to one Kleinanzeigen category (e.g. Fahrräder & Zubehör). Leave empty for all categories. You can also browse a whole category without keywords.

## `priceMin` (type: `integer`):

Only output listings at or above this price. Applied to the scraped results (the site's own price filter URLs are disallowed by its robots.txt), so a narrow range may page through more results. Listings without a price ("VB" only) are skipped when a price filter is set.

## `priceMax` (type: `integer`):

Only output listings at or below this price. "Zu verschenken" (free) listings count as 0 €. See Minimum price for how filtering works.

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

Optional: kleinanzeigen.de search result URLs copied from your browser (starting with https://www.kleinanzeigen.de/s-...). Category and attribute filters in the URL are kept. URLs that robots.txt disallows (radius, price, sort or seller-type filters) are skipped with a warning.

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

Maximum number of listings to output for each keyword / start URL. 0 = no limit (Kleinanzeigen shows at most 50 pages, about 1,250 listings, per search).

## `fetchDetails` (type: `boolean`):

Also open every ad page to add the full description, attributes (Art, Zustand, ...), all image URLs, seller type (private/commercial) and, for commercial sellers only, the business name. One extra request per listing, charged as a separate "listing-details" event.

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

Output only listings not output by an earlier run with the same "State key" (remembered in a named key-value store). The first run outputs everything and becomes the baseline. Schedule the Actor (e.g. hourly) for deal alerts.

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

Name of the memory used by "Only new listings". Use a different key per monitor so they don't share seen ads.

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

Usually not needed. If kleinanzeigen.de blocks the run (HTTP 403/429), enable Apify Proxy (automatic/datacenter). Residential proxies are not supported: if you pick the RESIDENTIAL group the Actor falls back to datacenter proxy.

## Actor input object example

```json
{
  "searchQueries": [
    "fahrrad"
  ],
  "location": "Berlin",
  "maxItems": 15,
  "fetchDetails": false,
  "onlyNew": false,
  "stateKey": "default",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `listings` (type: `string`):

One item per ad: title, price, price type, place, date, image and URL.

## `listingsFull` (type: `string`):

Every field, including ad details when fetched.

## `summary` (type: `string`):

Per-search status, counts, request statistics and warnings.

# 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"
    ],
    "location": "Berlin",
    "maxItems": 15,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("rjmacarthy/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"],
    "location": "Berlin",
    "maxItems": 15,
    "proxyConfiguration": { "useApifyProxy": False },
}

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

```

## MCP server setup

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