Kleinanzeigen Scraper & API: Ads, Prices, Places
Pricing
from $0.59 / 1,000 listings
Kleinanzeigen Scraper & API: Ads, Prices, Places
Scrape Kleinanzeigen.de ads (formerly eBay Kleinanzeigen) by keyword, category and city: title, price and VB, place, posting time, photos, mileage, rooms and m². Optional ad page: postcode, coordinates, seller type, all attributes. New ad monitor. Export JSON, CSV, Excel.
Pricing
from $0.59 / 1,000 listings
Rating
0.0
(0)
Developer
Automation Craft
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
21 hours ago
Last modified
Categories
Share
Kleinanzeigen Scraper & API: Ads, Prices, Places
Scrape Kleinanzeigen.de ads (formerly eBay Kleinanzeigen, Germany's largest classifieds site) into clean rows: title, price as a number with its type (fixed, VB, giveaway), city, posting time in Berlin time, category, photos, and the figures the results page shows for cars and flats (mileage, first registration, living space, rooms). Search by keyword, category and place, paste Kleinanzeigen search links, or give ad links. On request each ad's full page is added: the whole description, postcode, state and district, map coordinates, every attribute and photo, private or commercial seller, member since, badges, shipping and the seller's phone number where the ad page shows it without a login. Give the run a monitor name and schedule it: each run then delivers only the ads that are new.
No Kleinanzeigen account, no cookies, no API key, no browser. The Actor reads only pages every visitor can see, follows Kleinanzeigen's robots.txt and leaves private sellers' personal data out by default.
Who uses it
- Resellers and bargain hunters: a monitor on a narrow search (a model, a size, a price range) that delivers each new ad once, newest first, to a spreadsheet, Slack or e-mail through Apify's integrations.
- Car and property market research: prices, mileage, first registration, rooms and living space by city and category, with coordinates and postcodes from the ad pages.
- Small dealers: what competitors in their city list, at what price, with which photos.
- Data teams and agents: a structured Kleinanzeigen feed through the Apify API, one schema for every category.
Quick start
- Type what you want in Keywords (
fahrrad,iPhone 15), and optionally pick Categories (Autos,Mietwohnungen) and Places (Berlin,München,Hamburg-Mitte,Bayern). Every keyword is searched in every category and place you give. Or paste Search links from your browser, or Ad links. - Optional: set Maximum ads, the price filter, Posted within the last days, the car and property filters, or turn on Read the ad page of each ad.
- Click Start. Download the rows as JSON, CSV or Excel, or read them through the API.
- To get only new ads, give the run a Monitor name and schedule it (for example every hour).
How deep does a search go?
Each search reads the newest ads first, from page 1 to at most page 5, about 30 ads a page plus Kleinanzeigen's TOP ads,
so about 150 of the newest ads per search. Kleinanzeigen's robots.txt asks robots not to read pages 6 and later, nor to use
the site's own price, sort, radius or seller filters, and this Actor follows it. Depth comes from more searches: more
places (a city, its districts, a state), more categories, more keywords. The run tells you where that matters: every search
gets a free coverage row with the number of ads Kleinanzeigen says it holds, the pages read and whether the search held
more than five pages show (beyondReach). With Split searches that hold more than five pages on, such a search is
also searched in its sub categories (or the districts of its city, or the 16 states), one level deep.
What you get
One row per ad (type: "listing"). Fill rates measured on 1,437 results cards from 15 kinds of search and 45 ad pages
read on 2026-10-11 (FEASIBILITY.md in the source):
| Field | What it holds | Filled |
|---|---|---|
adId, url, title | Kleinanzeigen's ad id, the ad's address, the title | 100% |
description | the snippet the results page shows (about 150 to 250 characters); the full description when the ad page was read (descriptionComplete: true) | 100% |
price, priceText, priceType, currency | the price in EUR as a number, as written, and its type: fixed, negotiable (VB), free (Zu verschenken) or none | price figure 77% (jobs, VB alone and giveaways show none), type 100% |
city, locationId | the place the results page names, and Kleinanzeigen's id of the ad's postcode area | 100% |
categoryId, categoryName, parentCategoryId, parentCategoryName | the ad's category and its top category, by name | 100% |
postedAt, postedText | posting time in Berlin time: date and time for today and yesterday, the date for older ads | 100% of ads that are not TOP ads |
imageUrl, imageCount | the first photo and the number of photos | 100% |
mileageKm, firstRegistration | for vehicles, from the results card | on vehicle searches |
livingSpaceM2, rooms | for property, from the results card | on property searches |
tags, directBuy, onlineViewing, isTopAd, isHighlighted | the card's tags and flags (Direkt kaufen, online viewing, TOP ad, highlighted) | as shown |
searchLabel, searchKeyword, searchCategory, searchLocation, searchUrl, page, position | the search the row came from, its page and position | 100% |
With Read the ad page of each ad (billed as Listing details):
| Field | What it holds | Filled on ad pages |
|---|---|---|
description (full), postedDate, adType (offer or wanted) | the whole text, the posting date, offer or wanted | 100% |
postcode, state, district | from the ad page | postcode and state 100%, district 42% (cities with districts) |
latitude, longitude, coordinatesRounded | the map point; for private sellers rounded to 2 decimals (about 1 km) unless you opt in | 100% |
street | commercial sellers' street when shown (private sellers' only with the opt in) | 13% |
sellerType, sellerId, sellerMemberSince | private or commercial, Kleinanzeigen's user id, active since | 100% |
sellerName | commercial sellers always; private sellers only with Include private sellers' personal data | 100% for commercial sellers |
sellerBadges, sellerActiveAds, sellerProPage | badges such as TOP Zufriedenheit, ads online, the Pro shop page | 69%, 69%, 18% |
sellerPhone | the seller's phone number as written in the ad page a visitor who is not logged in gets (spaces collapsed); null when Kleinanzeigen shows the number only after a login, on rows without the ad page, and when the ad page is not built the way the Actor knows (it never guesses). On call tracking ads (some property and car dealer ads) a click on the site shows a forwarding number instead, which this Actor does not request. Private sellers' only with the opt in | 10 of 26 commercial ads, 0 of 30 private ads (56 ad pages, 2026-10-14) |
attributes, features, attributeCodes | every detail as the page lists it (Marke, Kilometerstand, Wohnfläche ...), amenity checks, the site's attribute codes | 78%, 24%, 84% |
images | every photo of the ad | 91% (some ads have none) |
shippingPossible, shippingText, promotedFeatures | shipping and its price, paid features (TOP ad, highlight, bump up) | as shown |
Example row (shortened):
{"type": "listing","adId": "3538233055","url": "https://www.kleinanzeigen.de/s-anzeige/3538233055","title": "Kinderfahrrad","price": 50,"priceType": "fixed","city": "Berlin","postedAt": "2026-10-11T18:21:00+02:00","categoryName": "Fahrräder & Zubehör","postcode": "13589","state": "Berlin","district": "Spandau","latitude": 52.57,"longitude": 13.16,"coordinatesRounded": true,"sellerType": "private","sellerName": null,"searchLabel": "Fahrräder & Zubehör in Berlin","page": 1,"position": 4}
Free rows, never charged: one coverage row per search (type: "search": the site's count, pages read, ads seen and
delivered, ads already delivered or known to the monitor, ads left out by filters, complete, beyondReach), status rows
(type: "status") for input that cannot be used, an ambiguous place or category name (with the candidates), an ad that no
longer exists, a search Kleinanzeigen did not apply as sent, and a run summary (type: "summary") at the end.
How much does it cost to scrape Kleinanzeigen?
Pay per event, with Apify's Store discounts by plan:
| Event | Free plan | Bronze | Silver | Gold |
|---|---|---|---|---|
| Listing (one ad row) | $0.00099 | $0.00089 | $0.00075 | $0.00059 |
| Listing details (the ad page of a delivered ad, only when ad pages are read) | $0.0012 | $0.0011 | $0.00095 | $0.0008 |
| Results page (only in monitor runs: one results page read, about 30 ads) | $0.00015 | $0.00015 | $0.00015 | $0.00015 |
| Actor start (once per run) | $0.004 | $0.004 | $0.004 | $0.004 |
Platinum and Diamond plans pay the Gold price. The Store pricing card shows these prices per 1,000 events: "$0.99 / 1,000" on the Listing row means one ad costs 0.099 cents.
Examples on the Free plan: 100 ads cost $0.004 + 100 x $0.00099 = $0.103. 1,000 ads cost $0.994. 1,000 ads with their ad pages cost $0.004 + 1,000 x ($0.00099 + $0.0012) = $2.194. An hourly monitor of 5 searches that reads 1 page each and finds 10 new ads costs $0.004 + 5 x $0.00015 + 10 x $0.00099 = $0.01465 per run.
Free: ads left out by your filters, ads already delivered in the run, ads a monitor delivered before, ads that no longer exist, searches Kleinanzeigen did not apply, invalid input, coverage rows, status rows and the summary. The seller type and offer type filters need each ad's page, so with them every delivered ad is billed as Listing plus Listing details.
Work that delivers nothing is bounded: a run may send 20 requests plus 2 per ad delivered, 10 per ad page delivered and 0.5 per Results page before it stops with a status row that says so. A filter that almost no ad passes, or a long list of ad links that no longer exist, ends there; narrow the search or split the list. A monitor's own results pages are paid as Results pages and never count against it.
Input
| Field | What it does |
|---|---|
keywords | Search words (fahrrad, iPhone 15). Hyphens read as spaces, as on the site. |
categories | Kleinanzeigen categories by name (Autos, Mietwohnungen), address word (autos, wohnung-mieten, also wohnung mieten) or id (216). 162 categories. |
locations | Places by name (Berlin, München), "Name, State" when a name exists in several states (Altdorf, Bayern), district (Hamburg-Mitte), state (Bayern) or id written l6411. About 12,000 places from Kleinanzeigen's own place list. |
searchUrls | Kleinanzeigen search addresses from your browser (keyword, category and place are used; addresses with filters are refused, see below). |
adUrls | Ad addresses or ad ids; each is read from its ad page and delivered with the ad page details. |
maxItems | Most ad rows this run delivers (default 100). |
maxPagesPerSearch | Result pages per search, 1 to 5 (default 5). |
splitLargeSearches | Also search the sub categories, districts or states of a search that holds more than five pages. |
includeDetails | Read each delivered ad's page (Listing details). |
includePrivateSellerDetails | Also deliver private sellers' personal data: name, street, phone number, exact coordinates and phone numbers in the texts as written (see below). |
minPrice, maxPrice | Price range in whole euros, applied by the Actor. Ads without a price figure are left out when it is set. |
maxAgeDays | Only ads posted within this many days; a search stops at its first older ad. |
minMileageKm, maxMileageKm, minFirstRegistrationYear, maxFirstRegistrationYear | Vehicle filters, applied by the Actor on the figures the ads show. |
minRooms, maxRooms, minLivingSpaceM2, maxLivingSpaceM2 | Property filters, applied by the Actor. |
includeTopAds | Include Kleinanzeigen's TOP ads (default on). |
sellerType | any, private or commercial (reads the ad pages). |
adType | any, offer or wanted (reads the ad pages). |
monitorName | A name for the monitor memory (new ads only). |
Example input:
{"keywords": ["e-bike"],"categories": ["Fahrräder & Zubehör"],"locations": ["München", "Hamburg"],"maxPrice": 1500,"maxAgeDays": 7,"maxItems": 200}
The monitor: new ads only
Give the run a Monitor name and schedule it. The monitor is a named memory of every ad id it delivered: a later run
with the same name and the same settings delivers and bills only ads that are new to it; ads it delivered before are
skipped for free. A monitor run pays a Results page event per results page it reads. If more new ads arrived between two
runs than the pages read hold, the coverage row says so (newestUnseenPossible: true): raise the pages per search or run
more often. A monitor name belongs to one set of settings; use a new name for other searches. Schedule runs on one name so
they do not overlap (an overlapping run reads nothing and says why).
FAQ
Does Kleinanzeigen have an API?
Kleinanzeigen offers no public API for its listings. This Actor reads the public pages any visitor sees and gives you the ads as rows that you can read through the Apify API, with no key from Kleinanzeigen.
How do I get notified about new Kleinanzeigen ads?
Run a search with a Monitor name on an Apify schedule (every hour, for example). Each run delivers only the ads that are new to the monitor; connect the run to Slack, e-mail, Google Sheets or a webhook with Apify's integrations.
How do I export Kleinanzeigen ads to Excel or CSV?
Run the Actor, then download the dataset as Excel, CSV or JSON from the run page, or read it through the Apify API. Every category has the same columns.
Why does a search stop at about 150 ads?
Kleinanzeigen's robots.txt asks robots not to read result pages 6 and later, and this Actor follows it: each search reads its 5 newest pages. To go deeper, search more places, categories or keywords, or turn on Split searches that hold more than five pages; the coverage row of each search shows how many ads Kleinanzeigen says it holds.
Is it allowed to scrape Kleinanzeigen?
This Actor reads only public pages without logging in, follows Kleinanzeigen's robots.txt and leaves private sellers' personal data out by default. You are responsible for a lawful use of the data you collect, including personal data under the GDPR and Kleinanzeigen's terms.
What does "Include private sellers' personal data" change?
Off (the default), a private seller's row, and every row without its ad page (it cannot tell private from commercial),
has sellerName, street and sellerPhone empty, coordinates rounded to about 1 km, and phone numbers the seller wrote
into the title, description or any other text replaced by [phone number removed] where the Actor recognises them as
phone numbers. On, all of it is delivered as the page shows it to a visitor who is not logged in. Commercial sellers'
details are always delivered. Price and events are the same either way.
Why does this Actor run with limited permissions?
It needs no access to your other Apify data. It only writes to its own run's dataset and key-value store and, when you use a monitor, to one named key-value store it creates itself for that monitor.
What this Actor does not do
- No phone number that needs a login: Kleinanzeigen shows many sellers' numbers, and every private seller's number we
checked, only to logged in users, so
sellerPhoneis null for those ads. Numbers commercial sellers write into titles and descriptions are delivered as written; private sellers' with the personal data switch on. - No more than five result pages per search, no radius search and no Kleinanzeigen sort orders or site filters: robots.txt of Kleinanzeigen asks robots not to use them. Price, age, seller type, offer type, mileage, first registration, rooms and living space are filtered by the Actor instead.
- No postcode search: Kleinanzeigen's place lookup is an address robots.txt disallows. Use place names, districts, states or place ids.
- No view counts: each view count read would count a visit on the seller's ad.
- No price history and no tracking of deleted ads: the monitor delivers new ads only. To be told about new ads in Slack or by e-mail, connect one of Apify's integrations to the run.
- No messages, no posting and nothing behind a login.
- No list of all ads of one seller: the seller's ad list page is disallowed by robots.txt.
- No photo download: photo addresses are in every row.
API
curl -X POST "https://api.apify.com/v2/acts/automation_craft~kleinanzeigen-scraper/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \-H "Content-Type: application/json" \-d '{"keywords": ["fahrrad"], "locations": ["Berlin"], "maxItems": 20}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });const run = await client.actor('automation_craft/kleinanzeigen-scraper').call({ keywords: ['fahrrad'], locations: ['Berlin'], maxItems: 20 });const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.filter((x) => x.type === 'listing'));
from apify_client import ApifyClientclient = ApifyClient("YOUR_API_TOKEN")run = client.actor("automation_craft/kleinanzeigen-scraper").call(run_input={"keywords": ["fahrrad"], "locations": ["Berlin"], "maxItems": 20})rows = [x for x in client.dataset(run["defaultDatasetId"]).iterate_items() if x["type"] == "listing"]
Changelog
See the Changelog tab.