How to use it: 3 steps
- Make a free Apify accountApify is the cloud platform where our tools run. The free plan gives you $5 of usage every month, no credit card needed. You pay Apify, not us.
- Paste your input and press StartNo code needed: you fill in a form (the input). It already has a working example. For example:
fahrradin Search terms. Each start is one run. - Download the resultsWhen the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.
This tool is an Apify Actor: a small program that runs on Apify. You can also run it on a schedule, for example every Monday. New to it? Read how it works, step by step and the 8 words you need first.
What it does
Scrape classified ads from Kleinanzeigen.de, Germany's biggest classifieds site, by keyword, city or postal code, radius, category, price and seller type. Each row has the title, price and price type (fixed, VB or free), place and postal code, posting date, full description, all photos, private or commercial seller, shipping and the listing's attributes. No login, cookies or account. A 20-listing search costs $0.0305 on the Free plan.
- Keyword: one search per keyword, such as
fahrrad,iphone 13orsofa. Write keywords in German, as buyers do. - Location: a German city, district or 5-digit postal code, such as
Berlin,Münchenor10115, plus a radius from 5 to 200 km. - Category: 154 Kleinanzeigen categories, such as Autos, Fahrräder & Zubehör, Mietwohnungen or Smartphones.
- Price: minimum and maximum in euros.
- Seller type: private people or commercial sellers (shops and dealers).
- Kleinanzeigen URLs: paste a search URL to use its own filters, or listing URLs to refresh single listings.
Good for
- Track prices of used bikes, phones, furniture or cars in one city.
- Get new listings for a search every hour or every day with
onlyNew. - Compare private and commercial sellers in a category.
- Check if listings you saved earlier are still online (listing URLs).
Not a good fit
- Seller names, phone numbers or e-mails. They are not collected, and phone numbers or e-mails typed into the text are masked (numbers written out in words are not detected).
- Other classifieds sites, or listings outside Germany.
- More than 1,250 listings for one search. Kleinanzeigen shows at most 50 pages of 25 listings. Split a big search by price, city or category to get more.
- Sorting other than newest first (for keyword searches).
Who uses it
People who sell things
See what a similar sofa, bike or phone sells for before you set your price.
Resellers and deal hunters
Get new deals soon after they appear.
Market researchers
Track used prices for bikes, phones or cars in a city.
Price
Pay per event: you pay for each result the tool saves, plus a small start fee for each run. The price includes Apify platform costs. Apify bills you, not us. Prices below are for the Apify free plan.
| What you pay for | Price | When |
|---|---|---|
| Start fee | $0.002 | Charged once per run. This tool uses 1 GB of memory or less by default; more memory costs more. |
| Search lookup | $0.0005 | One search read on Kleinanzeigen (charged after its first result page), or one requested listing URL that no longer exists. |
| Listing | $0.0014 (from $0.00119 on paid Apify plans) | One Kleinanzeigen listing saved to the dataset. Duplicates, listings already seen in only-new mode and not_found rows are not charged as listings. |
Examples
- One listing: about $0.0039.
- 1,000 listings: about $1.40.
- Every day 100 listings, for 30 days: about $4.27 a month.
Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed. That is enough for about 3,500 listings.
Prices checked on 24 October 2026. See the current price on Apify.
Questions
Do I need a Kleinanzeigen account or proxy?
No. The tool reads public search and listing pages.
Can I get the seller's phone number?
No. Seller names and contacts are not collected. Use the listing link.
Can I search the whole of Germany?
Yes. Leave the location empty.
How many listings can one search return?
Up to 1,250 per search. That is the site's own limit.
Is it allowed?
Looking at public ads to compare prices is the normal use of this tool. It reads only ads that anyone can see without an account, like in a browser, only faster. Do not use the data to write to people or to copy their photos or texts for your own ads. If you use the data for a business, read the Kleinanzeigen terms first.
How do I get price history?
Each run gives the current listings. Schedule the same input and keep the datasets, or put the listing URLs in startUrls. Use id to follow one listing over time; originalPrice shows the price before the last price drop.
Details
Step by step on Apify
- Open the Input tab.
- Keep Search terms as
fahrradand Location asBerlin(the prefill). - Keep Max listings per search at
20. - Click Start.
- Open the Listings view of the dataset. Check
title,price,locationandpostedAt.
Use cases
| Task | Input | Key fields | Next step |
|---|---|---|---|
| Watch used bike or phone prices in a city | queries, location, radiusKm, priceMin, priceMax | price, priceType, attributes, location | Sort by price in a spreadsheet |
| Get new deals as soon as they appear | queries + location + onlyNew: true | title, price, url, postedAt | Schedule the run every hour |
| Rental market report | category: wohnung-mieten, location, radiusKm | price, attributes, postalCode, latitude, longitude | Group by postalCode |
| Find shops and dealers in a category | category + sellerType: commercial | title, price, location, shipping | Count listings per place |
| Check if saved listings still exist | startUrls with listing URLs | status, statusReason, price | Remove sold listings from your list |
Tips for better results
- Write keywords in German, like fahrrad or sofa, as buyers do.
- Paste a Kleinanzeigen search URL to reuse its own filters.
- Use originalPrice to spot listings with a recent price drop.
Limits and good to know
Data comes from the public search and listing pages of Kleinanzeigen.de. The Kleinanzeigen terms limit automated access and reuse of its content. You are responsible for checking that your use of the data is allowed. This Actor is an independent tool. It is not made by or endorsed by Kleinanzeigen.
- Search results. Kleinanzeigen decides which listings match a keyword and a place. The Actor does not promise every listing on the site
- 1,250 per search. The site shows at most 50 pages of 25 listings. When a search has more,
RUN_SUMMARYsays so; split it by price range, city or category - Dates. The site shows the time only for today and yesterday. Older listings have the date only
- TOP ads. Paid TOP ads are skipped by default, because they repeat on every page and are not new
- Privacy. Seller names, user IDs, phone numbers and the legal notice (Impressum) are never collected. Phone numbers and e-mails typed into the title or text are replaced with
[phone removed]/[email removed]. Masking is automatic: a number written out in words or digit by digit can stay in the text - Changes. If Kleinanzeigen changes its website, a run can fail with
SOURCE_ERRORuntil the Actor is updated
For developers
Sample result
One result from a real test run, in JSON. Real values change from run to run. In Excel or CSV each field is a column.
{
"id": "3540986756",
"url": "https://www.kleinanzeigen.de/s-anzeige/damenfahrrad-cityrad-schwarz-mit-korb/3540986756-217-3529",
"title": "Damenfahrrad Cityrad schwarz mit Korb",
"price": 100,
"priceType": "negotiable",
"originalPrice": null,
"currency": "EUR",
"location": "14169 Berlin - Zehlendorf",
"postalCode": "14169",
"latitude": 52.4424884,
"longitude": 13.264024,
"postedAt": "2026-10-14T17:57:00+02:00",
"description": "Ich verkaufe mein zuverlässiges Cityrad für Damen in klassischem Schwarz. Es ist ein ideales Fahrrad für den täglichen Weg durch die Stadt oder zum Einkaufen. …",
"images": [
"https://img.kleinanzeigen.de/api/v1/prod-ads/images/db/db4c5738-d020-4987-a595-4c687f2de989?rule=$_59.AUTO",
"https://img.kleinanzeigen.de/api/v1/prod-ads/images/f6/f65b85e8-c647-492f-9355-dd31c3ee853d?rule=$_59.AUTO"
],
"imageCount": 6,
"sellerType": "private",
"shipping": false,
"buyNow": false,
"isTopAd": false,
"categoryId": 217,
"categoryName": "Fahrräder & Zubehör",
"attributes": {
"Art": "Damen",
"Typ": "Cityräder",
"Zustand": "Gut"
},
"detailLevel": "full",
"status": "complete",
"statusReason": null,
"searchQuery": "fahrrad",
"searchUrl": "https://www.kleinanzeigen.de/s-berlin/sortierung:neuste/fahrrad/k0l3331",
"rank": 1,
"source": "kleinanzeigen.de",
"fetchedAt": "2026-10-14T15:58:03.899Z"
}Use it from code
Actor ID: cliqtomedia/kleinanzeigen-scraper. You need your Apify API token from Apify Console → Settings → API & Integrations.
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cliqtomedia/kleinanzeigen-scraper").call(run_input={
"queries": [
"fahrrad"
],
"location": "Berlin"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)curl -X POST "https://api.apify.com/v2/acts/cliqtomedia~kleinanzeigen-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"queries": ["fahrrad"], "location": "Berlin"}'# pip install langchain-apify
# set APIFY_TOKEN in your environment
from langchain_apify import ApifyActorsTool
tool = ApifyActorsTool("cliqtomedia/kleinanzeigen-scraper")
result = tool.invoke({"run_input": {"queries": ["fahrrad"], "location": "Berlin"}})
print(result)The cURL call waits for the results, up to 300 seconds. For longer runs, start a run (/runs) and get the results with a webhook or by checking the run. Apify API docs. LlamaIndex, MCP for AI agents and the JavaScript client: AI agents & MCP.
Data fields (30)
| Field | Type | Meaning |
|---|---|---|
id | string | Kleinanzeigen listing ID (Anzeigen-ID), stable across runs. |
url | string | Listing URL on www.kleinanzeigen.de. |
title | string | Listing title. Phone numbers and e-mails in it are masked. |
price | number | Price in euros; 0 for free items (Zu verschenken); null when the seller gave no price. |
priceType | string | fixed, negotiable (VB) or free (Zu verschenken). |
originalPrice | number | Earlier price shown crossed out after a price drop; null otherwise. |
currency | string | Always EUR. |
location | string | Place as shown on the listing, e.g. Berlin - Mitte. |
postalCode | string | German postal code of the listing. |
latitude | number | Approximate latitude from the listing page (area, not exact address). |
longitude | number | Approximate longitude from the listing page (area, not exact address). |
postedAt | string | Posting time: ISO date-time with Berlin offset for today and yesterday, otherwise the date (YYYY-MM-DD). |
description | string | Full description from the listing page, or the short teaser when details are off or unavailable. Phone numbers and e-mails in it are masked. |
images | array | Photo URLs in gallery order. |
imageCount | integer | Number of photos the listing has. |
sellerType | string | private or commercial seller. Seller names and contacts are never collected. |
shipping | boolean | true when shipping is offered (Versand möglich), false for pickup only. |
buyNow | boolean | true when the listing offers Direkt kaufen (buy with the site's payment); null for listing URLs. |
isTopAd | boolean | true for paid TOP ads (only when Include paid TOP ads is on); null for listing URLs. |
categoryId | integer | Kleinanzeigen category ID of the listing. |
categoryName | string | German category name. |
attributes | object | Listing attributes from the detail table, e.g. Art, Typ, Zustand. |
detailLevel | string | full when the listing page was read, card when fields come from the result list only. |
status | string | complete; partial when the listing page could not be read (card fields only); not_found when a listing no longer exists (never charged as a listing). |
statusReason | string | Plain-English reason for partial and not_found rows; null when complete. |
searchQuery | string | Search term that found the listing; null for URL inputs and keyword-less searches. |
searchUrl | string | Canonical Kleinanzeigen search URL that found the listing. |
rank | integer | Position among saved listings of that search (1 = newest). |
source | string | Always kleinanzeigen.de. |
fetchedAt | string | When the row was scraped (ISO 8601, UTC). |
Input settings (14)
The main fields of the input form. With the API you send them as JSON.
| Setting | Name in the API | Type | Example value |
|---|---|---|---|
| Search terms | queries | array | ["fahrrad"] |
| Location (city or ZIP) | location | string | "Berlin" |
| Radius around the location (km) | radiusKm | string | "0" |
| Category | category | string | |
| Minimum price (€) | priceMin | integer | |
| Maximum price (€) | priceMax | integer | |
| Seller type | sellerType | string | "all" |
| Max listings per search | maxItems | integer | 20 |
| Kleinanzeigen URLs | startUrls | array | |
| Open each listing for full details | includeDetails | boolean | true |
| Include paid TOP ads | includeTopAds | boolean | false |
| Only new listings (for alerts) | onlyNew | boolean | false |
| Only-new state name | stateKey | string | |
| Proxy | proxyConfiguration | object | {"useApifyProxy": false} |