# Kleinanzeigen Free Finds (`lowlanddata/kleinanzeigen-free-finds`) Actor

Everything being given away free ("zu verschenken") around a German location, as clean JSON. First run is a baseline; every scheduled run after delivers only NEW finds - built for hourly schedules with email or Slack. No seller data, ever. Pay per find.

- **URL**: https://apify.com/lowlanddata/kleinanzeigen-free-finds.md
- **Developed by:** [Lowland Data](https://apify.com/lowlanddata) (community)
- **Categories:** E-commerce, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.69 / 1,000 results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Kleinanzeigen Free Finds — new "Zu verschenken" items, delivered while they still exist

Kleinanzeigen.de has a whole category of things people give away for free — furniture, bikes, appliances, moving boxes, firewood. The catch: good give-aways are claimed within minutes, so checking the site by hand means arriving late every time.

This actor watches the **"Zu verschenken"** category around a German location and remembers what it has already shown you. Run it on a schedule and every run delivers **only the finds that are new since the last run** — hook an email, Slack or webhook integration onto it and fresh free stuff lands in your inbox instead of on someone else's trailer.

It is a satellite of the [Kleinanzeigen.de Scraper](https://apify.com/lowlanddata/kleinanzeigen-scraper), built on the same GDPR-first rule: seller names, IDs and profiles are never collected, and location stays at postcode level.

### Quick start (30 seconds)

1. Put your city in **location** — e.g. `Berlin` — and pick a **radiusKm** (default 10).
2. Click **Start**. The first run is a baseline: it records everything currently on offer and delivers it once.
3. Create a **Schedule** in the Apify Console (hourly works well) with the same input, and add an email or Slack integration. From now on, each run delivers only what appeared since the previous one.

That's the whole product: no re-reading the same fifty ads, no diffing exports by hand.

### What you can build with it

- **Get the sofa before anyone else.** Bargain hunters and zero-waste households: an hourly schedule with an email integration turns the give-away category into an alert feed — you click through while the ad is minutes old.
- **Source stock for flipping and upcycling.** Watch `searchQuery: "schrank"` or `"fahrrad"` around your city; free furniture and bikes with a photo and a direct link are raw material at zero purchase cost.
- **Furnish a student room for the price of a van rental.** Track your university town for a few weeks before moving; desks, shelves and kitchen gear show up free every day.
- **Feed a Sozialkaufhaus or social project.** Charities and donation-based shops can watch a whole region for give-away household goods and react before the ads expire.
- **Collect scrap and metal systematically.** `searchQuery: "schrott"` or `"metall"` plus a wide radius gives collectors a route-planning feed instead of a morning of browsing.

### What you get

Each find is one dataset item:

```json
{
  "listingId": "2098800001",
  "url": "https://www.kleinanzeigen.de/s-anzeige/schrank-zu-verschenken/2098800001",
  "title": "Schrank zu verschenken",
  "description": "Gut erhaltener Kleiderschrank, nur Abholung.",
  "priceType": "GIVEAWAY",
  "location": "80331 München",
  "postedAt": "Heute, 10:15",
  "imageUrl": "https://img.kleinanzeigen.de/api/v1/prod-ads/images/example.jpg",
  "adType": "offer",
  "shippingPossible": false
}
```

Field notes, so you know exactly what you are buying:

- `priceType` is always `GIVEAWAY`. The site occasionally slips priced ads into the give-away category; those are dropped by design, so this feed can never quietly turn into a priced feed.
- `adType` matters: `wanted` marks "Gesuch" ads — people *asking* for free items rather than offering them. They are flagged, not hidden, so you can keep or filter them with one condition.
- `location` is the postcode and locality the site displays, e.g. `80331 München` — never a street address.
- `postedAt` is the site's own display text (`Heute, 10:15`, `Gestern, 18:40`, or a date) — useful for judging how fresh a find is at a glance.
- `description` is the search-result snippet, enough to decide whether to click through.
- `shippingPossible` is rare for give-aways but worth a filter if you can't drive.

### What does it cost?

$1.99 per 1,000 finds delivered — and because runs after the baseline deliver only what's new, "delivered" means a handful of items per run, not a whole category dump.

- **A one-city baseline of 200 finds ≈ $0.40**, once.
- **An hourly schedule catching ~10 new finds a day ≈ $0.60/month.**
- **Empty runs — the common case at 3 a.m. — cost nothing.**

The price is all-inclusive: platform usage is covered, there is no separate compute bill. Failed runs are free. Free Apify plans get a 25-item sample per run — enough to see the output shape against your own city before scheduling anything.

### Not technical? Let your AI assistant set it up

Copy this into ChatGPT, Claude or any AI assistant, fill in the one line, and follow the conversation:

```text
Help me set up the "Kleinanzeigen Free Finds" actor on Apify
(https://apify.com/lowlanddata/kleinanzeigen-free-finds). Guide me one step at a time.

What I want: [E.G. "free furniture within 20 km of Köln, emailed to me as it appears"]

Guide me to:
1. Propose my input values: location (my German city, e.g. "Köln"), radiusKm
   (how far I'd drive to pick something up, up to 200), optional searchQuery
   (a German keyword like "schrank" or "fahrrad" if I only want one kind of item),
   and maxItems.
2. Create a free Apify account (apify.com), open the actor page, paste the values
   into the Input form, and start a run. Explain that this first run is a baseline:
   it delivers everything currently offered, and later runs deliver only new finds.
3. Set up an hourly Schedule in the Apify Console with the same input, and add an
   email integration on the runs so every new free find arrives in my inbox
   automatically.
4. If I want to watch a second city too, show me how to add another Schedule with a
   different location and a different stateStoreName so the two watches don't mix.
5. Show me how to export past finds as CSV/Excel if I ever want the history.
6. If it works, remind me at the end to leave a quick rating on the actor page, and
   to report anything broken on its Issues tab.
```

### Input

| Field            | Description                                                                                                                         |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `location`       | German city or region name, e.g. `Berlin` — resolved via the site's own location search. Leave empty to sweep all of Germany.       |
| `radiusKm`       | Search this many km around the location (1–200, default 10). Needs a location.                                                      |
| `searchQuery`    | Optional keyword inside the give-away category, e.g. `schrank` or `fahrrad`. Leave empty for everything.                            |
| `maxItems`       | Stop after this many finds. Default 200; free-plan runs are capped at 25.                                                           |
| `stateStoreName` | Named store remembering which finds were already delivered. Use a different name per watch to track several searches independently. |
| `resetState`     | Forget everything seen so far and deliver the current snapshot as a fresh baseline.                                                 |

Every input is optional — an empty input watches all of Germany, though a location plus radius is what most schedules want.

### Use it from your code

Scoped runs finish in seconds, so the one-call endpoint works well:

```bash
curl "https://api.apify.com/v2/acts/lowlanddata~kleinanzeigen-free-finds/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -X POST -H "Content-Type: application/json" \
  -d '{"location": "Berlin", "radiusKm": 20}'
```

Node.js:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('lowlanddata/kleinanzeigen-free-finds').call({
  location: 'Berlin',
  radiusKm: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("lowlanddata/kleinanzeigen-free-finds").call(
    run_input={"location": "Berlin", "radiusKm": 20})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

Schedules, webhooks and the Make/Zapier/n8n integrations all apply — this is a standard Apify actor, and the only-new-finds behavior makes it a natural trigger source: a webhook fires only when there is actually something to act on.

### Use it with AI agents (MCP)

MCP-capable agents — Claude, Cursor and friends — can run this actor as a tool through Apify's hosted MCP server: the agent sets the location, starts the run and reads the finds itself.

Claude Code:

```bash
claude mcp add apify --transport http "https://mcp.apify.com?actors=lowlanddata/kleinanzeigen-free-finds"
```

Cursor or Claude Desktop (add a custom connector / MCP server with this URL):

```text
https://mcp.apify.com?actors=lowlanddata/kleinanzeigen-free-finds
```

Sign in with your Apify account when prompted — runs are billed to it. Setup details per client: [Apify MCP docs](https://docs.apify.com/platform/integrations/mcp), or start from this actor's own MCP page: [apify.com/lowlanddata/kleinanzeigen-free-finds/api/mcp](https://apify.com/lowlanddata/kleinanzeigen-free-finds/api/mcp).

Prompts that work once connected:

- "Check for new free furniture within 15 km of Hamburg and list anything with a photo."
- "What's being given away near Leipzig right now? Skip the Gesuch ads."
- "Watch for free bikes around München and tell me the moment one shows up."

### Is it legal to scrape Kleinanzeigen give-aways?

Give-away listings are public commercial-classifieds data, and this actor is built so the sensitive part never enters your dataset: seller names, IDs, phone numbers and profile links are structurally absent from the output — there is no switch to flip, the fields simply do not exist. Location stays at the postcode-plus-locality level the site itself displays.

Requests are paced to keep the load on the marketplace negligible, and no anti-bot protections are bypassed. One honest limit, same as the parent scraper: the title and snippet are the lister's own words, delivered as-is — if someone types their phone number into their ad text, that text is not rewritten.

### Troubleshooting

- **"N free finds (baseline run)"** — this is the first run against a fresh state store: everything currently on offer, delivered once. Subsequent runs switch to new-only.
- **Every run delivers a full snapshot instead of only new finds** — each schedule needs its own `stateStoreName` if you run several watches; two watches sharing default input but different queries against the same store will fight each other. Give each watch its own name.
- **"Markup may have changed"** — when a run's items all come back without titles, the actor fails loudly instead of delivering junk. Report it on the Issues tab; markup changes get fixed quickly.
- **A blocked run** keeps whatever it collected before the block — you get partial results and a clear status, not silence.
- **Only 25 items on the free plan** — that's the free-plan sample cap; a paid Apify plan removes it.

### Is there a Kleinanzeigen API for free items?

No — Kleinanzeigen publishes no public listings API, for give-aways or anything else. This actor is the practical alternative: the "Zu verschenken" category as structured JSON, on a schedule, deduplicated across runs, through one HTTP call or as an MCP tool.

### Does Kleinanzeigen block scrapers?

The give-away category is served as regular server-rendered pages, and this actor stays polite: paced requests, standard datacenter proxies, runs scoped to one location that finish in seconds. No CAPTCHA battles and no residential-proxy surcharge. If a run does get blocked mid-way, it keeps what it collected and says so in the status.

### How do I monitor Kleinanzeigen for free stuff?

You don't need to build anything — this actor **is** the monitor. Set your location and radius, run once to establish the baseline, then create an hourly Schedule in the Apify Console with an email, Slack or webhook integration on the runs. The cross-run memory means every notification contains only genuinely new finds; a run with nothing new delivers nothing and costs nothing. The run's status message tells you which mode it was in: "N free finds (baseline run)" versus "N new free finds since the last run".

### FAQ

**How do I get notified about free furniture in Berlin?** Set `location: "Berlin"`, optionally `searchQuery: "möbel"` or `"schrank"`, schedule the actor hourly, and add an email integration on the runs. After the baseline, every email contains only new finds.

**What does "Zu verschenken" mean?** "To give away" — Kleinanzeigen's category for items offered for free. This actor watches only that category.

**What does "Gesuch" mean?** A wanted ad: someone *asking* for free items rather than offering them. These carry `adType: "wanted"` so one filter removes them; everything offered has `adType: "offer"`.

**Why did my first run deliver so many items?** That was the baseline: with an empty state store, the actor delivers everything currently on offer once, so the memory has something to compare against. Every later run against the same store delivers only what's new.

**How does the actor know which finds are new?** It keeps a record of every delivered listing ID in a named key-value store (`stateStoreName`). A find is delivered once and then remembered — across runs, across days.

**Can I watch two cities at the same time?** Yes — one Schedule per city, each with its own `stateStoreName` (e.g. `free-berlin` and `free-koeln`). The memories stay separate, so neither watch swallows the other's finds.

**What does resetState do?** It wipes the memory for that store name: the next run behaves like a first run and delivers the full current snapshot as a new baseline. Use it after changing your search, or when you want to start over.

**Why is an item already gone when I click the link?** Because free stuff on Kleinanzeigen moves in minutes — that is exactly why this actor exists. An hourly (or tighter) schedule with an instant email is the difference between reading about the sofa and owning it.

**Can a priced ad sneak into my feed?** No. Listings carrying a price are dropped by design, even when the site shows them inside the give-away category — `priceType` is always `GIVEAWAY`.

**Can I search for a specific item, like a free bike?** Yes — set `searchQuery` to a German keyword (`fahrrad`, `schrank`, `waschmaschine`). The search runs inside the give-away category only.

**Can I watch all of Germany?** Yes — leave `location` empty. Pair it with a `searchQuery` unless you genuinely want every give-away in the country.

**Will I get the seller's name or phone number?** No, structurally: those fields are never collected. You get the listing, its postcode-level location and a direct link — contacting the lister happens on Kleinanzeigen itself, as it should.

**How precise is the location?** Postcode plus locality, exactly as the site displays it (e.g. `80331 München`). Never a street address.

**How fast is a run?** Seconds — a scoped city watch reads a few result pages and stops. That's what makes tight schedules affordable.

**What does it cost per month?** $1.99 per 1,000 delivered finds, all-inclusive. Since post-baseline runs deliver only new items and empty runs are free, a typical one-city hourly watch costs well under a dollar a month.

**Can I export the finds to Excel or CSV?** Yes — every run's dataset exports as CSV, Excel, JSON or XML from the Apify Console or API. Each run holds its own batch of new finds.

**Does it work with Make, Zapier or n8n?** Yes — standard Apify actor, all integrations apply. The new-only output makes it a clean trigger: a webhook fires only when there is something worth reacting to.

**Can ChatGPT or Claude check for free stuff for me?** Yes — connect the actor through Apify's hosted MCP server (see the MCP section) and any MCP-capable agent can set the location, run it and read the finds.

**I want prices too, not only give-aways.** Then you want the parent actor: the [Kleinanzeigen.de Scraper](https://apify.com/lowlanddata/kleinanzeigen-scraper) covers the whole marketplace with prices, categories and full specs. This satellite does one thing — free finds, new-only — and stays cheap at it.

### Related scrapers

Same builder, same GDPR-clean output guarantee:

- [Kleinanzeigen.de Scraper](https://apify.com/lowlanddata/kleinanzeigen-scraper) — the parent: the full marketplace with prices, categories, specs and large-crawl support.
- [Marktplaats.nl Scraper](https://apify.com/lowlanddata/marktplaats-scraper) — the Netherlands' largest marketplace.
- [2dehands & 2ememain Scraper](https://apify.com/lowlanddata/tweedehands-scraper) — Belgium's largest second-hand marketplaces.

### Support

Something broken, or a field missing that you need? Open an issue on the actor's **Issues tab** — this actor is actively maintained and markup changes get fixed fast.

If it caught you something good, a **rating on this page** takes ten seconds and helps the next bargain hunter find it.

# Actor input Schema

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

German city or region name, e.g. "München" or "Berlin" - resolved via the site's own location search. Leave empty to sweep all of Germany.

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

Search this many km around the location (up to 200, default 10). Needs a location.

## `searchQuery` (type: `string`):

Optional keyword inside the give-away category, e.g. "schrank" or "fahrrad". Leave empty for everything.

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

Stop after this many finds. Free-plan runs are capped at 25 items.

## `stateStoreName` (type: `string`):

Named store remembering which finds were already delivered, so scheduled runs emit only new ones. Use a different name to track several searches independently.

## `resetState` (type: `boolean`):

Forget everything seen so far and deliver the current snapshot as a fresh baseline.

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

Proxy settings. Keep Apify proxy enabled.

## Actor input object example

```json
{
  "location": "Berlin",
  "radiusKm": 10,
  "maxItems": 25,
  "stateStoreName": "kleinanzeigen-free-finds-state",
  "resetState": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `finds` (type: `string`):

Give-away listings, one JSON object per find.

# 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 = {
    "location": "Berlin",
    "radiusKm": 10,
    "maxItems": 25,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lowlanddata/kleinanzeigen-free-finds").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 = {
    "location": "Berlin",
    "radiusKm": 10,
    "maxItems": 25,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("lowlanddata/kleinanzeigen-free-finds").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 '{
  "location": "Berlin",
  "radiusKm": 10,
  "maxItems": 25,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call lowlanddata/kleinanzeigen-free-finds --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lowlanddata/kleinanzeigen-free-finds"
        }
    }
}

```

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/2I8B9haYWlt2eupU9/builds/Rb3XKdm5yfF5PgcDp/openapi.json
