# Kleinanzeigen Scraper & API: Ads, Prices, Places (`automation_craft/kleinanzeigen-scraper`) Actor

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.

- **URL**: https://apify.com/automation_craft/kleinanzeigen-scraper.md
- **Developed by:** [Automation Craft](https://apify.com/automation_craft) (community)
- **Categories:** E-commerce, Real estate, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.59 / 1,000 listings

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### 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

1. 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**.
2. 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**.
3. Click **Start**. Download the rows as JSON, CSV or Excel, or read them through the API.
4. 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):

```json
{
  "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:

```json
{
  "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 `sellerPhone` is 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

```bash
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}'
```

```javascript
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'));
```

```python
from apify_client import ApifyClient
client = 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.

### More data tools by Automation Craft

- [Airbnb Scraper: Prices, Calendar, Reviews](https://apify.com/automation_craft/airbnb-scraper)
- [Amazon Product Scraper - Search, Best Sellers](https://apify.com/automation_craft/amazon-data-scraper)
- [UK EPC Register Scraper - Energy Certificates](https://apify.com/automation_craft/uk-energy-certificate-scraper)
- [Trustpilot Reviews Scraper: Coverage Per Company](https://apify.com/automation_craft/trustpilot-reviews-scraper)
- [Google Trends Scraper - Compare and Trending Now](https://apify.com/automation_craft/google-trends-scraper)
- [Meta Ads Library Scraper - Ad Library, All Filters](https://apify.com/automation_craft/meta-ads-library-scraper)

# Changelog

This Actor's version history is a separate document: https://apify.com/automation_craft/kleinanzeigen-scraper/changelog.md

# Actor input Schema

## `keywords` (type: `array`):

Search words as you would type them on Kleinanzeigen, for example fahrrad, iPhone 15 or Wohnung. A keyword cannot contain / \ : + ? # or %.

## `categories` (type: `array`):

Kleinanzeigen categories by name (Autos, Fahrräder & Zubehör, Wohnung mieten), by address word (autos, fahrraeder) or by id (216). A name two categories share is answered with a free row listing both ids.

## `locations` (type: `array`):

German cities, towns, city districts or states by name (Berlin, München, Hamburg-Mitte, Bayern), as "Name, State" when a name exists in several states (Altdorf, Bayern), or by Kleinanzeigen place id written as l6411. Postcodes and radius searches are not supported.

## `searchUrls` (type: `array`):

Kleinanzeigen search addresses copied from your browser, for example https://www.kleinanzeigen.de/s-fahrraeder/berlin/c217l3331. Their keyword, category and place are used. Links that carry filters (price, sort, radius, seller type, offer type, shipping) are refused with a free row, because robots.txt of Kleinanzeigen asks robots not to use them; use the price settings below instead.

## `adUrls` (type: `array`):

Single ads by link (https://www.kleinanzeigen.de/s-anzeige/...) or by ad id (3538233055). Each is read from its ad page and delivered with the ad page details. An ad that no longer exists gets a free row.

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

The most ad rows this run delivers, over all searches and ad links. Default 100.

## `maxPagesPerSearch` (type: `integer`):

Result pages read per search, newest ads first, about 30 ads a page. At most 5: robots.txt of Kleinanzeigen asks robots not to read pages 6 and later. Default 5.

## `splitLargeSearches` (type: `boolean`):

When a search holds more ads than five pages show, also search its sub categories (or, for a category without sub categories, the districts of its city, or the 16 states for a search without a place), one level deep, up to 50 extra searches per search. Every ad is delivered once. Off by default.

## `includeDetails` (type: `boolean`):

Adds the full description, postcode, state and district, coordinates, all attributes and photos, seller type, seller id, member since, seller badges, shipping and the seller's phone number where the ad page shows it without a login. Each ad delivered this way is billed as Listing plus Listing details. Off by default.

## `includePrivateSellerDetails` (type: `boolean`):

Adds a PRIVATE seller's personal data as the ad page shows it to a visitor who is not logged in: the seller's name (sellerName), street (street), phone number (sellerPhone, where the page shows it without a login), exact coordinates (latitude, longitude, coordinatesRounded false), and phone numbers written into the title, description, attributes, tags or any other text of the row, as written. Off (default): those fields are null, coordinates are rounded to about 1 km and phone numbers in the row's texts are replaced by \[phone number removed]. A row without its ad page cannot tell private from commercial and is treated as private. Commercial sellers' details are always included. You are responsible for a lawful use of personal data, the GDPR included. Off by default.

## `minPrice` (type: `integer`):

Leave out ads below this price, in whole euros. Ads without a price figure (VB alone, jobs) are left out when a price filter is set. With ad pages read, the price the ad page states decides.

## `maxPrice` (type: `integer`):

Leave out ads above this price, in whole euros. Ads without a price figure are left out when a price filter is set.

## `maxAgeDays` (type: `integer`):

Only ads posted within this many days before the run started. A search stops at its first older ad (the results are newest first). TOP ads show no date and are left out when this is set.

## `minMileageKm` (type: `integer`):

Vehicles: leave out ads below this mileage. An ad that shows no mileage is left out when a mileage filter is set.

## `maxMileageKm` (type: `integer`):

Vehicles: leave out ads above this mileage. An ad that shows no mileage is left out when a mileage filter is set.

## `minFirstRegistrationYear` (type: `integer`):

Vehicles: leave out ads first registered before this year. An ad that shows no first registration is left out when this filter is set.

## `maxFirstRegistrationYear` (type: `integer`):

Vehicles: leave out ads first registered after this year.

## `minRooms` (type: `integer`):

Property: leave out ads with fewer rooms. An ad that shows no room count is left out when a rooms filter is set.

## `maxRooms` (type: `integer`):

Property: leave out ads with more rooms.

## `minLivingSpaceM2` (type: `integer`):

Property: leave out ads with less living space. An ad that shows no living space is left out when this filter is set.

## `maxLivingSpaceM2` (type: `integer`):

Property: leave out ads with more living space.

## `includeTopAds` (type: `boolean`):

TOP ads are paid placements Kleinanzeigen shows on every results page, outside the date order. Included by default; each is delivered once.

## `sellerType` (type: `string`):

Only private or only commercial sellers. This needs the ad page of every ad, so ad pages are read and each delivered ad is billed as Listing plus Listing details.

## `adType` (type: `string`):

Only offers (Angebote) or only wanted ads (Gesuche). This needs the ad page of every ad, so ad pages are read and each delivered ad is billed as Listing plus Listing details.

## `monitorName` (type: `string`):

A short name such as bikes-berlin. Letters, digits, spaces and . \_ , - : # ( ), up to 60 characters. A name belongs to one set of settings; use a new name for other searches. Schedule runs on one name so they do not overlap.

## Actor input object example

```json
{
  "keywords": [
    "fahrrad"
  ],
  "locations": [
    "Berlin"
  ],
  "maxItems": 10
}
```

# Actor output Schema

## `items` (type: `string`):

No description

# 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 = {
    "keywords": [
        "fahrrad"
    ],
    "locations": [
        "Berlin"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation_craft/kleinanzeigen-scraper").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 = {
    "keywords": ["fahrrad"],
    "locations": ["Berlin"],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation_craft/kleinanzeigen-scraper").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 '{
  "keywords": [
    "fahrrad"
  ],
  "locations": [
    "Berlin"
  ],
  "maxItems": 10
}' |
apify call automation_craft/kleinanzeigen-scraper --silent --output-dataset

```

## MCP server setup

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

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/Ugev5d3VYZbafGblv/builds/Mo0ixWZ00VPN060SF/openapi.json
