Kleinanzeigen Scraper & API - Listings, Prices & Price Drops
Pricing
from $0.40 / 1,000 listings
Kleinanzeigen Scraper & API - Listings, Prices & Price Drops
Monitor Kleinanzeigen listings by search, city and price range. Get asking prices, VB, price drops, location and listing links as CSV/JSON. Return only new listings and price changes across runs, or add full descriptions and attributes. Built for resellers and market research.
Pricing
from $0.40 / 1,000 listings
Rating
0.0
(0)
Developer
gianluca de dominicis
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Features
Share
Kleinanzeigen Scraper & API - Listings, Prices & Price Drops
Deutsch: Schnellstart · English guide
Deutsch: Schnellstart
Kleinanzeigen finden, Angebotspreise vergleichen und Änderungen verfolgen. Suche auf Kleinanzeigen.de nach Begriff, Ort und Preisbereich oder füge einen Suchlink ein. Exportiere die Ergebnisse als CSV, Excel oder JSON – zum Beispiel für die Suche nach gebrauchten Smartphones, Fahrrädern oder anderen Waren zum Wiederverkauf.
Erster Test: bis zu 50 iPhone-Angebote in Berlin
- Gib bei Search terms
iphone 15und bei LocationBerlinein. Setze Category aufPhones & telecom, Radius (km) auf10und beide Ergebnislimits (Max listings per search und Max listings for the whole run) auf50. - Lasse Include listing details zunächst ausgeschaltet (
includeDetails: false) und lege unter Max cost per run ein Ausgabenlimit fest. - Klicke Start und lade nach dem Lauf die Ergebnisse als CSV, Excel oder JSON herunter. Ein Kleinanzeigen-Login ist nicht erforderlich.
Kosten dieses Tests: Werden 50 Anzeigen ohne Details zurückgegeben, beträgt der Preis zum Basistarif etwa 0,03 US-Dollar. Die Zahl verfügbarer Ergebnisse kann geringer sein. Die Basisrate beträgt 0,60 US-Dollar je 1.000 Ergebniszeilen; mögliche Tarifrabatte sind hier nicht berücksichtigt.
Beschreibungen und Attribute benötigt? Aktiviere Include listing details. Der zusätzliche Preis beträgt 2,00 US-Dollar je 1.000 erfolgreich abgerufene Details und fällt nur bei detailsStatus: "complete" an. Bei 50 Ergebniszeilen und 50 erfolgreichen Detail-Abrufen wären es insgesamt etwa 0,13 US-Dollar zum Basistarif. Einzelne optionale Angaben können auf der Quellseite fehlen.
Wiederholt nach neuen Anzeigen und Preisänderungen suchen
Aktiviere onlyNewListings und verwende bei späteren Läufen denselben monitorKey sowie dieselben Suchfilter. Der erste Lauf eines neuen Monitors liefert passende Anzeigen; spätere Läufe liefern neue Anzeigen und Änderungen gegenüber dem zuletzt beobachteten Preis. Auch Preiserhöhungen werden erfasst.
previousObservedPrice ist der zuvor vom Monitor beobachtete Preis. oldPrice ist dagegen der auf Kleinanzeigen durchgestrichene Preis. Beide sind Angebotspreise, keine nachgewiesenen Verkaufspreise.
deduplicateAcrossSearches: true vermeidet standardmäßig doppelte Anzeigen bei überlappenden Suchen. Mit false werden bewusst getrennte, jeweils berechnete Ergebniszeilen je Suche ausgegeben.
Wichtig: Zeitpläne, Google Sheets und Benachrichtigungen müssen separat in Apify, n8n, Make oder einem anderen Dienst eingerichtet werden. Preisalarme sind nicht automatisch aktiv. Verfügbare Seiten, Suchfilter sowie Ergebnis- und Kostenlimits beeinflussen die Erfassung; vollständige Marktabdeckung und die Erkennung verkaufter Anzeigen werden nicht zugesichert.
Neu in Version 0.3: Kategorien direkt auswählen, Angebote und Gesuche trennen, Direktkauf und Fotos filtern sowie nach Datum, Preis oder Entfernung sortieren. Mit einem globalen Ergebnislimit und getrennten Seiten-/Zeitlimits bleibt auch ein wiederholter Monitor ohne Neuigkeiten begrenzt. RUN_SUMMARY zeigt gelesene Seiten, ausgelassene ungültige Karten und den Grund für einen Abbruch der Suche. Preise und bestehende Monitor-Historien bleiben unverändert.
Anpassbare JSON-Beispiele · Monitoring im Detail · Preise und Abrechnung
English guide
Track the listings and asking prices that matter to your resale business. Search Kleinanzeigen.de by keyword, location and price range, or paste a search URL. Export structured results to CSV, Excel or JSON, then use Only new listings and price changes for repeat checks instead of downloading unchanged ads again.
Start with a lightweight price feed, and request full descriptions and attributes only when you need them. The optional details event is charged only when details extraction succeeds. By default, overlapping searches return a listing once per run.
Use it for electronics sourcing, local bicycle searches and asking-price research. Notifications and spreadsheet updates require an Apify schedule or an external workflow; they are not switched on automatically.
Three ready-to-edit inputs · Monitoring and price changes · Deutsch: Schnellstart
⭐ Found this Actor useful? Leave a review — it takes 30 seconds and helps other people find it.
🛠️ Something not working? Open an issue with the run link, expected behavior and observed result. We review reported issues; resolution time depends on the cause.
What you get for each listing
- 💶 Price, VB / negotiable, price drop (the crossed-out old price), free listings ("Zu verschenken")
- 📍 Postcode and district, posting date and time (German time), shipping possible, PRO seller and shop name, photo count
- 📝 With details: full description, attributes (brand, model, condition, size…), category path, all photos, shipping options ("+ Versand ab 2,99 €"), private or commercial seller and "active since"
- 🔔 Only new listings and price changes: compare with the last observed price, including both decreases and increases
- ✅ Explicit detail status: distinguish details that were not requested, obtained successfully or could not be retrieved
Quick start: the prefilled form requests up to 20 of the newest "iphone" listings in Germany, without details (about $0.012 at the base rate if 20 listings are returned). It also sets a three-page scan cap and a 120-second soft work limit. Then choose your words, category and location, or paste a search link. No Kleinanzeigen login is needed. Set Max cost per run before starting; listing details are a separate, optional charge. Existing API calls that omit the new controls keep the prior defaults: 100 results per search, with the new global/page/time caps disabled.
Real results — bikes in Berlin (+10 km), 100–300 €, October 2026, as shown on kleinanzeigen.de:
| Listing | Price | Old price | Postcode | Posted | Shipping | Condition |
|---|---|---|---|---|---|---|
| Author Profile Mountainbike silber 26 Zoll | 125 € | 170 € | 10711 Charlottenburg | Oct 10 | + Versand ab 0,99 € | Sehr Gut |
| Rennrad Stadler One Series 1.2 | 220 € VB | — | 12043 Neukölln | Oct 11, 02:34 | Nur Abholung | In Ordnung |
| Riverside 500 C6 L Fahrrad / Hybrid Bike | 250 € | — | 10115 Mitte | Oct 11, 03:14 | Nur Abholung | Sehr Gut |
Why this Kleinanzeigen scraper?
| Data collection challenge | This Actor |
|---|---|
| Unverified data | Checked against the live site: 200 of 200 fields identical on 20 listings (title, price, VB, postcode, district, shipping, seller type, active since, category, description) |
| Stop at 1,250 listings: Kleinanzeigen shows at most 50 pages per search | Expanded coverage for priced listings: big searches are split into price bands and merged without duplicates — bikes in Berlin (+10 km): 23,644 of the 24,251 listings the site reported (97.5%; listings without a price can't be split by price) |
| Different listing-page layouts | Extraction supports the classic and newer layouts represented in the saved test pages; future source changes can still require an update |
| Only the current price | Source-reported crossed-out prices and, in monitoring mode, comparison with your own last observed price |
| Re-download everything | Only new listings and price changes relative to the monitor's last observation |
| The same ad matches several searches | Deduplication across searches is enabled by default; disable it explicitly if you need separate query rows |
| Seller names and phone numbers of private people | Dedicated seller identity fields omitted: no private seller names, no phone numbers — business names only for commercial sellers |
| Inflate view counters to read them | Never touches the ad's view counter (reading it would count a fake visit for the seller) |
Coverage depends on source availability, filters and accessible pages; complete coverage is not guaranteed. Any validation figures below or above describe historical samples, not a guarantee of future accuracy or uptime.
Use cases
- Deal hunters and resellers: follow new listings and asking-price changes for saved searches, using a schedule you configure.
- AI agents: "find a used road bike under 500 € within 20 km of Munich" — through the Apify integration.
- Price research: real asking prices by model, condition and region — for cars, electronics, furniture, rentals.
- Dealers: see what competitors list, at which prices, and how often they cut them.
- Market monitoring: supply and price trends in any category, city by city.
How to use
- Enter Search terms (e.g.
iphone 15,rennrad), choose an optional Category, Location and Radius (km) — or paste Search links with any category and category-specific filters. Select a category with no words to browse that category. - Optional: Min / Max price, Seller, Listing type (offers / wanted), Buy now, Photos only, and Sort by. Nearest-first sorting requires a location and positive radius.
- Set Max listings per search and Max listings for the whole run. The first reached limit wins; 0 disables that cap. For regular monitoring, also set Max search pages per search and a soft time limit. Turn on Include listing details only if you need descriptions and attributes.
- Click Start and download the results as JSON, CSV or Excel, or fetch them via API.
New search controls and bounded monitoring
| Input | Purpose | Omitted value for existing API calls |
|---|---|---|
category | Guided shortlist: electronics, phones, desktop PCs, bicycles, home/garden and cars. Other categories remain available through URLs. Applies only to generated keyword/category searches. | "all" |
offerType | "offered" for offers or "wanted" for wanted ads. "any" keeps an existing URL filter. | "any" |
buyNowOnly / photosOnly | Source direct-purchase filter / exclude cards without listing photos before requesting details or charging. | false |
sortBy | "newest", "price_asc", "distance", or "inherit". Inherit keeps URL sorting and the existing sortNewest fallback. Promoted ads can still affect source ordering. | "inherit" |
maxTotalListings | Total saved rows across all searches, after filtering and deduplication. Stops optional detail requests once reached. | 0 (disabled) |
maxSearchPagesPerSearch | Search-page attempts per original search, shared across all its price bands. Bounds work even with zero new monitor outputs. HTTP retries and detail requests are separate. | 0 (disabled) |
maxRunSeconds | Soft run-wide work deadline; a request already in progress may finish later. Use Apify's timeout for a hard deadline. | 0 (disabled) |
Changing an explicit filter changes the monitor's search identity. Enabling photosOnly creates a separate baseline; turning it off restores the prior unfiltered identity. New neutral controls and new result/page/time caps do not reset existing histories.
Check RUN_SUMMARY, not just the row count. It includes per-search pages attempted, observed and saved listings, skipped invalid cards, stopReason, truncated, and global limit counters. A successful run with zero updates means no updates were returned from the pages actually checked, not that the whole market is unchanged. A partially invalid page can return its valid cards, with a warning and no charge for skipped cards. A page with no valid recognizable results and no genuine empty-search signal still fails visibly. If Kleinanzeigen refuses or throttles a request, the run switches automatically to German residential proxies (rotating IPs) and then to datacenter proxies; if one search still cannot be loaded, the listings already saved are kept, the run finishes with a note and that search is marked error in RUN_SUMMARY. An input the site cannot use (for example an unknown location) ends the run with an "Input problem" status message, no results and no charge.
Category-specific shipping attributes in pasted URLs (for example +fahrraeder.versand_s:ja for bicycles) are preserved. There is no universal shipping checkbox: the source uses different attributes for different categories.
Three ready-to-edit inputs
Paste an example into the JSON input editor, adjust its filters and set a spending limit. These are starting configurations, not promises of a particular number of available ads. maxListingsPerSearch applies to each search; overlapping results are deduplicated by default.
1. iPhone listings in Berlin: lightweight monitoring
The first run of this monitor returns matching listings within your limits. Later runs return new ads and observed price changes. Keep the same monitorKey and search configuration for subsequent runs.
{"searchTerms": ["iphone 15"],"location": "Berlin","radiusKm": 10,"minPrice": 200,"maxPrice": 600,"sellerType": "private","sortNewest": true,"maxListingsPerSearch": 50,"includeDetails": false,"onlyNewListings": true,"monitorKey": "berlin-iphone-15","deduplicateAcrossSearches": true}
At the base rate, 50 returned listings cost about $0.03. This example does not request the details add-on.
2. Road bikes in Munich: condition and attributes
Use the details option when descriptions and category-specific attributes help you assess a listing. The example requests a snapshot; turn on onlyNewListings and set a stable monitorKey if you want to repeat it as a monitor.
{"searchTerms": ["rennrad"],"location": "München","radiusKm": 20,"minPrice": 200,"maxPrice": 800,"sellerType": "private","sortNewest": true,"maxListingsPerSearch": 100,"includeDetails": true,"onlyNewListings": false,"deduplicateAcrossSearches": true}
If 100 listings are returned and all 100 detail extractions succeed, the base-rate event cost is about $0.26. Optional source fields can still be absent.
3. Model and asking-price research: overlapping searches
Compare public asking prices for a model and a more specific variant across Germany. Deduplication prevents the same ad being returned twice when both searches match it. Inspect condition and attributes before comparing prices: asking prices are not completed-sale prices or a valuation.
{"searchTerms": ["thinkpad t14", "thinkpad t14 gen 2"],"minPrice": 100,"maxPrice": 700,"sortNewest": true,"maxListingsPerSearch": 50,"includeDetails": true,"onlyNewListings": false,"deduplicateAcrossSearches": true}
Monitoring and price changes
- Set
onlyNewListings: trueto remember the latest observed price for each ad in a search. A fresh monitor emits the initial matching listings asnew; later runs emit new ads and changes to the last observed price. For example, 100 → 80 → 100 → 80 contains three changes, not just one previously unseen price. monitorKeyis optional. Use a stable value to keep independent monitors separate, and reuse that value on subsequent runs. The search itself also forms part of the monitor's identity: changing filters creates a different search baseline. Omit the key to use the default monitor namespace.- Existing monitors created with the older ID/price history re-establish a current baseline once for known ads. Historical price order is not reconstructed; comparisons resume from that baseline. Version 2 writes separate records and preserves the old history for pinned older builds and rollback.
- Avoid concurrent runs of the same search and
monitorKey. Use one schedule per monitor or separate keys for independent workflows. - A monitor can only compare listings it actually reads. Result caps, budget limits, filters and source availability can leave some ads unobserved. The Actor does not promise to detect every market change or infer that an absent ad was sold.
Two different kinds of previous price: oldPrice and priceDropped describe the crossed-out price shown by Kleinanzeigen. previousObservedPrice and priceChange compare your monitor's observations across runs. These values may differ; neither is a completed-sale price.
Overlapping searches: deduplicateAcrossSearches defaults to true. Each ad is emitted once per run and attributed to the first matching search. Set it to false only when you intentionally want separate rows for matching searches; each returned row is then a billable listing event. Deduplication within an individual search remains in place.
Output
The output below is a separate historical example, not the response to the input example above. Values, dates and source availability change between runs.
By default, one item per unique listing in a run. This historical example is a €125 bike in Berlin, from a separate Berlin €100–€300 search, not the Munich €200–€800 input above. Include listing details was on; description and photo links are shortened. It predates the change/status metadata documented below:
{"adId": "3537089111","title": "Author Profile Mountainbike silber 26 Zoll","url": "https://www.kleinanzeigen.de/s-anzeige/author-profile-mountainbike-silber-26-zoll/3537089111-217-3344","price": 125,"priceText": "125 €","negotiable": false,"oldPrice": 170,"priceDropped": true,"zip": "10711","location": "Charlottenburg","postedDate": "2026-10-10","postedTime": "21:52","promoted": false,"shipping": true,"sellerIsPro": false,"imageCount": 3,"description": "Ich verkaufe mein Mountainbike, da ich auf ein anderes Rad umgestiegen bin. Es…","attributes": {"Art": "Herren","Typ": "Mountainbikes","Zustand": "Sehr Gut"},"category": "Fahrräder & Zubehör","categoryPath": ["Auto, Rad & Boot","Fahrräder & Zubehör"],"priceType": "FIXED","shippingText": "+ Versand ab 0,99 €","sellerType": "private","sellerActiveSince": "2026-05-25","images": ["https://img.kleinanzeigen.de/api/v1/prod-ads/images/cc/cc2c41a3-a6bc-4220-9091-ada969a946cb…","https://img.kleinanzeigen.de/api/v1/prod-ads/images/92/925e4031-85f9-4bba-b334-1377f2daa5ad…"],"scrapedAt": "2026-10-11T01:20:39.611Z"}
| Field | Meaning |
|---|---|
price / priceText | Asking price in euros as a number, and as shown ("899 € VB"); null when only "VB" is given |
negotiable | "VB" (Verhandlungsbasis) |
oldPrice / priceDropped | The previous price crossed out on Kleinanzeigen; this is not your monitor's previous observation |
postedDate / postedTime | When the listing was posted, German time ("Heute, 02:52" becomes today's date) |
promoted | A promoted listing (shown without a date) |
changedSinceLastRun | With Only new listings: whether the price changed from the monitor's last observation |
changeType | snapshot outside monitoring; new, price_decreased, price_increased or price_changed in monitoring mode |
previousObservedPrice | The monitor's previously observed asking price, where available; separate from the source's oldPrice |
priceChange / priceChangePercent | Change from the previous observed price where the comparison can be calculated; negative values mean a decrease |
detailsStatus | not_requested, complete or failed. The extra details event is charged only for complete; optional fields may still be absent on the source |
attributes | With details: the listing's attribute list, e.g. {"Marke": "Apple", "Zustand": "Sehr Gut"} |
sellerType / sellerActiveSince | With details: private or commercial, and since when the account exists |
How much does it cost?
Prices and examples below use base rates before plan discounts. The Store’s “from” price may reflect a higher-plan discount; check the Pricing tab for your current plan’s rate.
Pay per event — no monthly rental, no start fee, no proxy or compute surcharge:
- Listing — each returned listing row: $0.60 per 1,000.
- Listing details — successfully extracted details for a listing (only with Include listing details and
detailsStatus: "complete"): $2.00 per 1,000 more.
Examples: 100 listings ≈ $0.06; 1,000 listings with details ≈ $2.60. Set Max cost per run for a hard cap on spending.
If detail extraction fails but the base listing is returned, the base listing event still applies and the extra details event does not. Unchanged ads omitted by monitoring are not listing outputs. If you disable cross-search deduplication, the same ad can legitimately appear in multiple paid query rows.
Automate & integrate
Scheduling, notifications and external destinations require configuration in Apify or the relevant integration.
For a repeatable workflow, enable Only new listings and price changes, keep a stable monitorKey, and configure an Apify schedule. Call the Actor from any language through the Apify API, or route its output through n8n or Make.
Telegram alert for new listings and price drops (n8n, three nodes):
- Schedule Trigger — for example every 30 minutes.
- HTTP Request —
POST https://api.apify.com/v2/acts/surefeed~kleinanzeigen-scraper/run-sync-get-dataset-items, authenticated with your Apify token stored as an n8n credential (headerAuthorization: Bearer <token>), JSON body:
{"searchTerms": ["rennrad"],"location": "München","radiusKm": 20,"minPrice": 150,"maxPrice": 400,"sellerType": "private","onlyNewListings": true,"monitorKey": "rennrad-muenchen","maxListingsPerSearch": 25}
- Telegram → Send Message — one message per returned item, for example:
{{ $json.changeType === 'price_decreased' ? '📉 Preis gesenkt' : '🆕 Neue Anzeige' }}{{ $json.title }}{{ $json.priceText }}{{ $json.previousObservedPrice ? ' (vorher ' + $json.previousObservedPrice + ' €)' : '' }}{{ $json.zip }} {{ $json.location }}{{ $json.url }}
The first run returns the current matches; later runs return only new listings and price changes, so nothing is sent when nothing changed. Set a minPrice: without it, a search like "rennrad" also returns accessories. The request above was run against this Actor; the n8n node setup is a guide to adapt, and a failed run must be handled separately from a quiet one.
Manual n8n → Google Sheets setup:
- Configure your Apify and Google Sheets credentials in n8n; do not put tokens in the Actor input or in a shared workflow file.
- Use an n8n Schedule Trigger and Run Actor, or an Apify schedule with n8n's On new Apify event trigger. Choose one scheduling approach to avoid duplicate executions.
- Continue only after a successful run, then use Get Dataset Items with that run's
defaultDatasetId. - For a current-price table, update or insert rows keyed by
adId. For an observation history, keep each emitted observation with itsscrapedAt,changeTypeand price fields, and prevent duplicate appends when a workflow retries. - Optionally add an email, Slack or other notification step for the events you want. An empty dataset means there are no returned updates; a failed run must be handled separately, not treated as a quiet day.
This is a configuration guide, not a supplied, pre-tested SureFeed workflow template. External accounts and services require their own setup and may have separate costs. See the official Apify n8n guide or Make guide.
Use with AI assistants (MCP)
Add this Actor as a tool to Claude, ChatGPT, Cursor or any MCP client through the Apify MCP server (https://mcp.apify.com). Your assistant can then search Kleinanzeigen on demand.
Agent-ready: autonomous payments (x402 & Skyfire)
Where supported by Apify, agents can use platform payment integrations such as x402 or Skyfire. Availability, authentication and payment setup depend on Apify’s current integration requirements.
FAQ
How do you get past the 50-pages limit? Kleinanzeigen shows at most 50 pages (1,250 listings) per search. When a search has more, the Actor repeats it in price bands (halving any band that is still too big) and merges the results without duplicates. Listings without a price (only "VB") can't be found by price, so past the first 1,250 only priced listings are included.
How accurate is the data? We compared 20 listings (bikes in Berlin) with their pages on kleinanzeigen.de in a browser (October 2026): title, price, VB, postcode, district, shipping, seller type, active since, category and description — 200 of 200 values identical — and every attribute (brand, type, condition…) on all 20, on both page layouts Kleinanzeigen serves. Price drops matched the crossed-out price on the site.
Why is the posting date sometimes one day later than on the listing page? For listings posted just after midnight, Kleinanzeigen's listing page shows the previous day (it uses UTC), while the search shows "Heute". We use German local time.
Can I get the seller's name or phone number? No. Private sellers' names and phone numbers are personal data, so they're left out; for commercial sellers you get the business name.
Is it legal to scrape Kleinanzeigen? The Actor only reads public listings, the same data anyone sees on kleinanzeigen.de, without logging in. Check Kleinanzeigen's terms and your local laws (including GDPR) for your use case.
Something is broken — what now? Open an issue on the Issues tab with the run link. Include the expected behavior and observed result. Resolution time depends on the cause.
More tools from us
- Eventbrite Scraper & API — available events by city or online, with ticket prices, sold out and organizer details.
- Workday Jobs Scraper & API — available jobs from supported Workday careers sites, with exact posting date, salary range and remote status.
- Google Hotels Scraper & API — hotel prices with taxes, available booking partner offers, and hotels near any address.
- Google Flights Scraper & API — fares, stops, layovers and CO2 emissions for any route, flexible dates.
- Google Trends Scraper & API — interest over time, by region, related queries and trending searches.
- Google Play Scraper & API — Android app data, star histograms and reviews.
- App Store Scraper & API — iPhone app data, star histograms, top charts and reviews in 150+ countries.
Legal
Disclaimer: This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Kleinanzeigen GmbH or eBay. It only collects publicly available listings. All trademarks belong to their respective owners.