# Kleinanzeigen Scraper - Listings, Prices & New Ads Alert (`kamerozkan/kleinanzeigen-scraper`) Actor

Kleinanzeigen scraper and API: listings by keyword or any search URL with price, VB, location, date, shipping, seller type and photos, optional full details, plus new ads alerts and price drops since your last run. Pay per listing.

- **URL**: https://apify.com/kamerozkan/kleinanzeigen-scraper.md
- **Developed by:** [Kamer Ozkan](https://apify.com/kamerozkan) (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 $0.80 / 1,000 listings

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 - Listings, Prices & New Ads Alert

**Kleinanzeigen scraper and API: get every listing of a Kleinanzeigen search with price, VB flag, postal code, city, posting time, shipping, PRO shop and photos, and get alerted about new ads and price drops since your last run.** Type a search term like on kleinanzeigen.de (formerly eBay Kleinanzeigen), add a city or postal code and a radius, or paste any search URL from your browser. No login, API key or proxy setup needed.

### What does Kleinanzeigen Scraper do?

It opens the Kleinanzeigen search results for each search term or URL (25 listings per page, newest first, up to 50 pages) and saves every listing card: title, price and old price, VB (Verhandlungsbasis), postal code and city, posting time, shipping possible, Direkt kaufen, TOP ad flag, PRO shop name, photo count, first photo and a description snippet. Filter by location and radius, by a price range, or only listings with shipping.

Turn on **Include full details** and it also opens each listing page and adds the full description, all attributes (condition, type, size, brand, mileage, rooms and so on), the category path, seller type (private or commercial), exact posting date, shipping cost text, coordinates and all photos.

Give the run a **new ads alert key** and it remembers every listing it has seen: each row then shows `isNew`, `previousPrice`, `priceChange` and `firstSeenAt`. With **Only new listings and price drops** turned on, a scheduled run saves and charges only what is new since the last run, so you get a cheap Kleinanzeigen alert for any search.

### Who is it for?

- **Resellers and flippers**: get new listings for the items you buy (bikes, iPhones, consoles, furniture, tools) minutes after they go online, with price and location.
- **Car, bike and electronics dealers**: watch prices of used goods in your region and spot underpriced offers and price drops.
- **Market and price researchers**: collect used-goods prices by category, city and condition for price guides and valuation models.
- **Developers**: feed Kleinanzeigen listings into a database, a spreadsheet, Telegram or Slack alerts through the API.

### What data can you get?

| Field | Example |
|---|---|
| `adId` | `3542077246` |
| `title` | `Apple iPhone 15 Pro Titan Blau Sehr gut Zustand + OVP` |
| `url` | `https://www.kleinanzeigen.de/s-anzeige/.../3542077246-173-3511` |
| `price` / `priceText` | `450` / `450 €` |
| `negotiable` | `true` when the price says VB |
| `oldPrice` | `3979` (crossed-out price, if the seller lowered it) |
| `postalCode`, `city`, `location` | `12619`, `Hellersdorf` |
| `postedAt` / `postedText` | `2026-10-15T22:15:00Z` / `Heute, 00:15` |
| `shippingPossible`, `directBuy` | `true`, `false` |
| `isTopAd` | `false` (paid TOP listing pinned above the results) |
| `isProShop`, `shopName`, `shopUrl` | PRO shops (businesses) only |
| `imageUrl`, `imageCount` | first photo and number of photos |
| `descriptionSnippet` | first lines of the description |
| `search`, `page`, `position`, `totalResults`, `searchUrl` | where the listing was found |
| `isNew`, `previousPrice`, `priceChange`, `firstSeenAt` | new ads alert fields (with an alert key) |
| `description`, `attributes`, `categoryPath`, `categoryId`, `sellerType`, `priceType`, `adType`, `postedDate`, `shippingText`, `latitude`, `longitude`, `images` | with Include full details |
| `scrapedAt` | `2026-10-16T05:52:06Z` |

Private sellers' names and phone numbers are never collected; only the seller type (private or commercial) and the names of PRO shops, which are businesses.

### How much does it cost to scrape Kleinanzeigen?

You pay only for listings saved to your dataset: **$1.00 per 1,000 listings** on the Free plan ($0.001 per listing), $0.90 on Bronze, $0.85 on Silver and $0.80 on Gold and higher Apify plans. Full details cost the same per listing. Proxy traffic and platform usage are included.

Worked example: a new ads alert for 10 searches that runs every hour and finds about 20 new listings per search a day saves 200 listings a day, 6,000 a month: 6,000 x $0.001 = $6.00 a month on the Free plan. A single search of 100 listings costs $0.10.

Pages that Kleinanzeigen refuses are retried through other connections; searches that still cannot be read are listed in the `FAILED_SEARCHES` record of the run's key-value store and nothing is charged for them. Listings skipped by a filter (price, shipping, TOP ads, already seen) are not charged either. Set **Max listings in total** or a maximum cost per run to cap spending.

### How to use it

1. Click **Try for free**.
2. Enter one or more **search terms**, for example `fahrrad`, `iphone 15` or `ecksofa`.
3. Optionally add a **location** (city such as `Berlin` or a postal code such as `50667`) and a **radius**, a **price range**, **Only listings with shipping** or **Skip TOP ads**. Or paste **search URLs** copied from kleinanzeigen.de with any filters already set.
4. Turn on **Include full details** if you need attributes, full descriptions and the seller type.
5. For alerts, enter a **new ads alert key** such as `bikes-berlin`, turn on **Only new listings and price drops** and schedule the run (every hour or every day) in Apify.
6. Click **Start** and download the results as JSON, CSV or Excel, or read them through the API.

### Input example

```json
{
  "searches": ["iphone 15", "rennrad"],
  "location": "Berlin",
  "radiusKm": 20,
  "minPrice": 100,
  "maxPrice": 1500,
  "maxItemsPerSearch": 60,
  "skipTopAds": true,
  "monitorKey": "berlin-deals",
  "onlyNew": true,
  "maxItems": 200
}
```

### Output example

A real row from a test run on 2026-10-16 (search "iphone 15" in Berlin, 20 km, 100 to 1,500 EUR, alert key set, first run):

```json
{
  "adId": "3542077246",
  "title": "Apple iPhone 15 Pro Titan Blau Sehr gut Zustand + OVP",
  "url": "https://www.kleinanzeigen.de/s-anzeige/apple-iphone-15-pro-titan-blau-sehr-gut-zustand-ovp/3542077246-173-3511",
  "price": 450,
  "priceText": "450 €",
  "negotiable": false,
  "oldPrice": null,
  "currency": "EUR",
  "postalCode": "12619",
  "city": "Hellersdorf",
  "postedAt": "2026-10-15T22:15:00Z",
  "postedText": "Heute, 00:15",
  "shippingPossible": false,
  "isTopAd": false,
  "isProShop": false,
  "imageCount": 10,
  "descriptionSnippet": "Verkaufe mein iPhone 15 Pro mit 128 Gb in der Titan Blau Farbe an befindet sich in Sehr gutem...",
  "search": "iphone 15 in Berlin",
  "position": 5,
  "totalResults": 611,
  "isNew": true,
  "previousPrice": null,
  "priceChange": null,
  "firstSeenAt": "2026-10-16T05:52:03Z",
  "scrapedAt": "2026-10-16T05:52:06Z"
}
```

With **Include full details** a row also has, for example:

```json
{
  "attributes": {"Art": "Herren", "Typ": "Cross- & Trekkingräder", "Zustand": "Neu"},
  "categoryPath": ["Auto, Rad & Boot", "Fahrräder & Zubehör"],
  "sellerType": "private",
  "priceType": "NEGOTIABLE",
  "postedDate": "2026-10-15",
  "shippingText": "+ Versand ab 23,99 €",
  "latitude": 47.7047,
  "longitude": 8.7486
}
```

The dataset has three views: **Overview** (photo, title, price, VB, PLZ, city, posted, shipping, PRO shop), **New ads and price drops** and **Details**.

### Integrations and API

Run it from your code with the Apify API or the `apify-client` package, schedule it in Apify, or connect it to Make, n8n, Zapier, Google Sheets, Telegram, Slack or a webhook.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("kamerozkan/kleinanzeigen-scraper").call(run_input={
    "searches": ["playstation 5"],
    "location": "Hamburg",
    "radiusKm": 30,
    "maxPrice": 350,
    "monitorKey": "ps5-hamburg",
    "onlyNew": True,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["price"], item["city"], item["title"][:60], item["url"])
```

### FAQ

**How do I get a Kleinanzeigen alert for new ads?** Enter a new ads alert key, turn on *Only new listings and price drops* and schedule the run, for example every 30 or 60 minutes. The first run saves everything it finds; later runs save only listings that were not there before and listings whose price dropped, and stop paging at the first page without new listings, so frequent runs stay fast. Connect a webhook, Telegram or email integration to get notified.

**Can I search one city or postal code?** Yes. Enter a city or a 5-digit postal code in *Location* and choose a radius (5 to 200 km). For anything else the website offers (category, seller type, condition, sorting), set the filters on kleinanzeigen.de and paste the URL into *Search URLs*.

**Does it work for Kleinanzeigen Immobilien and Autos?** Yes. Any Kleinanzeigen search works, including apartments, houses, cars and jobs categories. Turn on full details to get attributes such as rooms, living space, mileage or first registration.

**Why do some rows have no price?** Some listings only say VB or *Zu verschenken* (free). VB alone gives `price: null, negotiable: true`; free items give `price: 0`.

**Why is postedAt empty on some rows?** TOP ads pinned above the results do not show a posting time on the card. Turn on full details to get `postedDate` for every listing.

**Is it legal to collect this data?** It collects public listing data that Kleinanzeigen shows to every visitor, without logging in, and never collects private sellers' names or contact details. You are responsible for how you use it.

### Support and feedback

- Found a bug or missing a field? Open an issue on the **Issues** tab of this Actor. We reply within
  48 hours and ship most fixes within a few days.
- Have an idea for a feature? Issues are the fastest way to get it built.
- If the Actor saves you time, a short review on this page helps other users find it.

# Actor input Schema

## `searches` (type: `array`):

What you would type into the Kleinanzeigen search box, one per line, for example "fahrrad", "iphone 15" or "wohnung". Each search reads up to 25 listings per page, newest first.

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

Limit the search terms to a city or 5-digit postal code, for example "Berlin", "München" or "50667". Leave empty for all of Germany.

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

Distance around the location, as on the website: 5, 10, 20, 30, 50, 100, 150 or 200 km. Only used with a location.

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

Only listings from this price. Applied on Kleinanzeigen for search terms and again on every row, so start URLs are filtered too. Leave empty for no limit.

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

Only listings up to this price. Leave empty for no limit.

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

Any Kleinanzeigen search result URL copied from your browser, with category, location, radius, price or other filters already set, for example https://www.kleinanzeigen.de/s-berlin/fahrrad/k0l3331r10. Pages are followed automatically.

## `maxItemsPerSearch` (type: `integer`):

How many listings to read for each search term or URL (25 per page, up to 50 pages).

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

Open every listing page and add the full description, attributes (condition, type, size, mileage, rooms and so on), category path, seller type (private or commercial), exact posting date, coordinates and all photos. Slower (one extra page per listing); the price per listing stays the same.

## `onlyShipping` (type: `boolean`):

Keep only listings marked "Versand möglich". Other listings are not saved and not charged.

## `skipTopAds` (type: `boolean`):

Leave out the paid TOP listings that Kleinanzeigen pins above the newest results. Every row also has an isTopAd flag.

## `monitorKey` (type: `string`):

Any name, for example "bikes-berlin". Runs with the same key remember every listing they have seen, so each row gets isNew, previousPrice and priceChange. Schedule the run every hour or day for a new ads alert. Leave empty for a plain search.

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

With a new ads alert key: save (and pay for) only listings not seen in earlier runs, plus known listings whose price dropped. The first run saves everything it finds.

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

Stop after this many listings across all searches. You are charged per listing, so this also caps the cost of the run.

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

Apify Proxy is used by default; if a page is refused, the request is retried through German residential proxies. Proxy traffic is included in the price.

## Actor input object example

```json
{
  "searches": [
    "fahrrad"
  ],
  "maxItemsPerSearch": 100,
  "includeDetails": false,
  "onlyShipping": false,
  "skipTopAds": false,
  "onlyNew": false,
  "maxItems": 200,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

One row per result in the default dataset.

# 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 = {
    "searches": [
        "fahrrad"
    ],
    "maxItemsPerSearch": 100,
    "maxItems": 200,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("kamerozkan/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 = {
    "searches": ["fahrrad"],
    "maxItemsPerSearch": 100,
    "maxItems": 200,
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

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