Extract structured data from Kleinanzeigen.de — classified listings from Kleinanzeigen.de — prices, locations, images, descriptions, and seller contacts including phone and email. Filter by keyword, category and location; incremental runs return only new listings.
Kleinanzeigen Scraper on Apify →
No credit card required. No commitment. Cancel anytime.
- Click sign up — pick GitHub, Google, or email; takes ~30 seconds
- Open this actor — input is pre-filled with a working example
- Click Start — export results as JSON, CSV, or Excel
Your $5 monthly platform credit is enough to run this actor right away — and again every month — scraping typically several hundred to several thousand results per run, depending on your input.
Search with filters — Search by keyword and location. Filter by 📁 category, ✨ condition, 👤 seller type, and more.
Detail enrichment — Fetch full descriptions, contact information for each listing.
Incremental mode — Only get new or changed listings since your last run. Content hash per listing — no duplicates, no re-processing.
Change classification — Track unchanged, expired, cross-run repost detection across runs. Build audit trails of how listings evolve over time.
Compact output — Emit core fields only (AI-agent / MCP-friendly). Keeps response size small for LLM workflows.
Description truncation — Cap description length per listing to control output size and cost.
Result cap — Stop after N listings (up to 5.000). Set to 0 for the full catalog.
Export anywhere — Download as JSON, CSV, or Excel. Stream via Apify API, webhooks, or integrations with Make, Zapier, Airbyte, Keboola.
Structured data — Every listing returns the same schema with consistent field naming. All fields always present — null when unavailable, never omitted.
Data pipeline automation Integrate with your ETL pipeline to collect structured listings from Kleinanzeigen.de on a schedule. Export to CSV, JSON, or directly to your database. Use compact mode to control output size.
Market research Monitor listings, track trends, and analyze market dynamics with structured, deduplicated data from Kleinanzeigen.de.
Change monitoring Run daily or hourly in incremental mode to capture only new, updated, or expired listings. Perfect for price-tracking, churn analysis, and alerting pipelines.
Lead generation Extract contact details alongside listings to build targeted outreach lists for sales teams, partnerships, or B2B prospecting.
AI / LLM training data Structured JSON per listing is ready for RAG pipelines, embeddings, and agent workflows. Compact mode trims tokens for LLM context windows.
{
"query": "iPhone",
"location": "Berlin",
"maxResults": 10,
"includeDetails": true
}| Parameter | Type | Default | Description |
|---|---|---|---|
query |
string | — | Single keyword or phrase (e.g. 'iPhone', 'sofa', 'Fahrrad'). For multiple searches in one run, use the queries array below. |
queries |
array | [] |
Run multiple keyword searches in one go — e.g. ["laptop", "iPad", "AirPods"]. Results from all searches are merged and deduplicated by listing ID. Filters below (category, location, price, etc.) apply to all queries. Takes precedence over the single query field. |
startUrls |
array | [] |
Paste one or more Kleinanzeigen.de search-result URLs. Build the filters you want in your browser, copy the URL, and paste here. Each URL is paginated; results are merged and deduplicated. Takes precedence over query, queries, and all filter inputs. The legacy searchUrls field name is still accepted for backward compatibility. |
watchSellerIds |
array | [] |
Track specific sellers by their numeric seller ID — paste the IDs (or full seller-inventory URLs) and the run returns each seller's current listings. Takes precedence over search term, queries, and Start URLs. Combine with ♻️ Incremental Mode to get only a seller's new or changed listings each run. |
maxResultsPerQuery |
integer | 0 |
Cap per individual search when running multiple queries via queries. 0 = use the global Max Results for every query. Useful for balanced sampling across diverse searches. |
category |
enum | "all" |
Filter by Kleinanzeigen category. |
location |
string | — | City name or postal code to search within (e.g. 'Berlin', 'München', '10115'). Leave blank to search all of Germany. |
radius |
integer | 0 |
Proximity radius around the specified location in kilometres. Requires Location to be set. 0 = exact city match. Kleinanzeigen uses preset steps (5, 10, 20, 30, 50, 100, 150, 200 km) and snaps to the nearest. |
condition |
enum | "all" |
Filter by item condition. |
sellerType |
enum | "all" |
Filter by seller type. |
shipping |
enum | "all" |
Filter by shipping availability. |
adType |
enum | "angebote" |
Listing type: offers for sale, or wanted ads. |
priceMin |
integer | 0 |
Minimum price filter. |
priceMax |
integer | 0 |
Maximum price filter. 0 = no limit. |
sortBy |
enum | "newest" |
Sort order for results. |
whatAnd |
array | [] |
Keep only listings whose title (and description, when 📄 Enrichment is on) contains EVERY word listed here. Accent- and case-insensitive. Example: ["carbon", "rennrad"] keeps only carbon road bikes. Applied after fetching, so the returned count may be lower than Max Results. |
whatExclude |
array | [] |
Drop listings whose title (and description, when 📄 Enrichment is on) contains ANY of these words. Accent- and case-insensitive. Example: ["defekt", "bastler"] removes broken / for-parts listings. Applied after fetching, so the returned count may be lower than Max Results. |
postedWithin |
enum | "all" |
Keep only listings posted within this time window. 'Any time' applies no date filter. Applied after fetching, so the returned count may be lower than Max Results. |
maxResults |
integer | 25 |
Maximum total listings to return across all searches. 0 = unlimited. |
incremental |
boolean | false |
Only return new or changed listings since the last run. State is saved between runs and scoped per query and category. |
stateKey |
string | — | Custom key for incremental state storage. Defaults to a key derived from your search query and category. Use to share state across runs with minor input variations. |
emitUnchanged |
boolean | false |
In ♻️ Incremental Mode, also output listings that haven't changed since the last run (normally skipped). Off by default. |
emitExpired |
boolean | true |
In ♻️ Incremental Mode, output a stub row (changeType=EXPIRED) for listings that were present in a previous run but are now gone. On by default. |
skipReposts |
boolean | false |
In ♻️ Incremental Mode, suppress listings that look like a re-post of a previously expired one (same title, price, and location under a new ID). Off by default. |
includeDetails |
boolean | true |
Fetch the full listing page for each result to add description, images, category path, attributes, and more. Produces richer output but takes longer. |
includeSellerProfile |
boolean | false |
Fetch extra detail for each unique seller to add reputation badges and the seller's active-ads count. Adds one request per unique seller (a small per-seller charge applies) and increases run time. |
includePhone |
boolean | false |
Resolve and include the seller's contact phone number for each listing. Requires an additional request per listing. |
descriptionMaxLength |
integer | 0 |
Truncate listing descriptions to N characters. 0 = no truncation. |
descriptionFormat |
enum | "all" |
Pick a single description representation. all keeps every variant; text / html / markdown drops the others. |
compact |
boolean | false |
Return only the most essential fields (for AI-agent and MCP workflows). |
omitNulls |
boolean | true |
Drop null, empty string, empty array, and empty object fields from each output row. Reduces dataset size and removes noise for LLM pipelines. Keeps false and 0 as valid values. Default on — disable if you need a fixed schema where every row has every documented field. |
excludeEmptyFields |
boolean | false |
Drop null, empty-string, and empty-array fields from each record before push. Smaller payloads for AI agents and dashboards. |
telegramToken |
string | — | Telegram bot token (from @BotFather). Required for Telegram notifications. |
telegramChatId |
string | — | Telegram chat or channel ID (e.g. "-100123456789"). Required when telegramToken is set. |
discordWebhookUrl |
string | — | Discord incoming webhook URL. Server Settings → Integrations → Webhooks → New Webhook. |
slackWebhookUrl |
string | — | Slack incoming webhook URL. api.slack.com/messaging/webhooks. |
whatsappPhoneNumberId |
string | — | Your WhatsApp Business phone-number ID (numeric, from Meta dashboard). Required when whatsappAccessToken is set. |
whatsappAccessToken |
string | — | WhatsApp Cloud API permanent access token (System User token from Meta Business). Recipient must have messaged the business number within the last 24 h. |
whatsappTo |
string | — | Recipient phone in E.164 format without + (e.g. "436641234567"). Recipient must have messaged your business number within the last 24 h. |
webhookUrl |
string | — | Receives a JSON POST with {metadata, items} after each run. Works with n8n, Make, Zapier, and custom backends. |
webhookHeaders |
object | — | Optional JSON object of custom headers (e.g. {"Authorization":"Bearer ..."}). |
notificationLimit |
integer | 5 |
Maximum number of listings included in each notification message (1–20). |
notifyOnlyChanges |
boolean | false |
When Incremental Mode is on, only send notifications for NEW and UPDATED listings. Has no effect outside incremental mode. |
appConnector |
string | — | Optional. Pick a connected app under Settings → API & Integrations to receive your results. Notion is supported today; other connectors are best-effort as Apify expands its catalog. |
mcpIssueTeam |
string | — | Only when the connected app is an issue tracker: the team (name or ID) the summary issue is created under, if that app requires one. |
Every listing returns the same 29-field schema. Missing values are null — never omitted.
listingIdtitleurlpricepriceTextcurrencythumbnaillocationpostedTextlatitudelongitudeattributessellercontentHashscrapedAtdescriptiondescriptionHtmldescriptionMarkdownimageUrlsimageUrlimageCountcategoryPathcategoryzipCodepriceTypeshippingAvailablesellerNamesellerIdportalUrl
One object per listing. Here is a real example from a production run:
{
"listingId": "3446804582",
"title": "Guess iPhone 17 Hülle Glitzer Pink Neu OVP",
"url": "https://www.kleinanzeigen.de/s-anzeige/guess-iphone-17-huelle-glitzer-pink-neu-ovp/3446804582-173-3421",
"price": 17,
"priceText": "17 €",
"currency": "EUR",
"thumbnail": "https://img.kleinanzeigen.de/api/v1/prod-ads/images/8f/8fc21359-d116-4ba3-9777-08a8191414db?rule=$_2.AUTO",
"location": "Steglitz",
"postedText": "Heute, 18:53",
"latitude": 52.44995,
"longitude": 13.32851,
"attributes": {
"Art": "Weitere Handys & Telefone",
"Versand": "ab 0,00",
"Farbe": "Pink",
"Gerät & Zubehör": "Zubehör",
"Zustand": "Neu"
}
}Truncated — full records contain 29 fields. See Output fields for the complete schema.
Try Kleinanzeigen Scraper now — $5 free credit, no credit card →
Pay only for what you extract. No subscription required — Apify's free $5 credit covers thousands of results.
| Event | Price (USD) |
|---|---|
| Actor Start | $0.005 |
| Result | $0.00135 |
| Seller Enrichment | $0.002 |
See the actor on Apify for current pricing.
How do I scrape Kleinanzeigen.de? Use this actor on Apify to extract structured data from Kleinanzeigen.de. Configure your search query and filters in the input, then click Start — no coding required.
How do I get Kleinanzeigen.de data as JSON, CSV, or Excel? The actor writes each listing to Apify's dataset. Download as JSON, CSV, or Excel from the Console, stream via the API, or push to Make, Zapier, Airbyte, or Keboola.
Is it legal to scrape Kleinanzeigen.de? Web scraping of publicly available data is generally legal. This actor only accesses publicly visible information. Always check Kleinanzeigen.de's terms of service for your specific use case.
How much does it cost? Pay-per-event pricing — you only pay for listings extracted. Apify's free $5 credit is enough to run thousands of results before you pay anything.
How does incremental mode work? Each listing gets a content hash. On subsequent runs, only new or changed listings are emitted — saving time, compute, and storage. Expired listings can be tracked separately.
Do I need an API key or credentials? No. Just sign up for Apify, paste your input, and click Start. No credit card required.
- Djinni Scraper — Ukraine & CEE tech jobs with salary and English level
- Work.ua Scraper — Ukraine's work.ua job listings
- NoFluffJobs Scraper — Poland & CEE IT jobs with transparent salary ranges
- OLX Jobs Scraper — OLX job listings across 7 CEE countries
- Prace.cz Scraper — Czech Republic's prace.cz job board
- Profession.hu Scraper — Hungary's profession.hu job board
Browse all Black Falcon Data actors →
New to Apify? Create a free account with $5 credit — no credit card required.
- Sign up — $5 platform credit included
- Open Kleinanzeigen Scraper and configure your input
- Click Start — export results as JSON, CSV, or Excel
Need more later? See Apify pricing.
Black Falcon Data builds production-grade web scrapers for job boards and marketplace data. Browse our full actor catalog at www.blackfalcondata.com.
Last updated: 2026 06