# Kleinanzeigen Resell Price Checker (`beltech/kleinanzeigen-resell-price-checker`) Actor

Price check for used items on Kleinanzeigen.de, built for AI agents and automations: sell price estimate, deal check, market statistics and alerts for new listings. Prices come from the ads currently listed for the same item, with accessories, bundles and defects filtered out.

- **URL**: https://apify.com/beltech/kleinanzeigen-resell-price-checker.md
- **Developed by:** [Bel](https://apify.com/beltech) (community)
- **Categories:** Agents, E-commerce, AI
- **Stats:** 2 total users, 1 monthly users, 50.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 Resell Price Checker

Find out what a used item is worth on Kleinanzeigen.de. Ask for a sell price, check whether a
price or an ad is a good deal or look up market prices. The answer is
based on what the same item is listed for on Kleinanzeigen right now, not on guesses.

Accessories, complete PCs, bundles, broken units, swap ads and other models are filtered out
before any price is calculated, so the number you get is the price of the item you asked about.

It is built for AI agents and automations: one call in, one clear result out. You can also run it
by hand with the form.

### Copy-paste prompt for your agent

Add this to your agent's instructions (Claude project instructions, a system prompt, or the start of
a chat). It tells the agent when and how to use this Actor.

```text
You can price used items on Kleinanzeigen.de with the Apify Actor
"beltech/kleinanzeigen-resell-price-checker". Call it with the Apify MCP tool call-actor
(actor name without a tool suffix), then read the result with get-dataset-items using the returned
datasetId. The run's statusMessage already contains a one-line answer.

WHEN TO USE IT
- The user wants to SELL a used item or asks what it is worth: action "estimate_sale_price".
- The user asks whether a price or an ad is a good deal: action "check_deal"
  (with "query" + "priceEur", or with "listingUrl").
- The user wants to see what is on offer: "search_listings". A market overview: "market_stats".
- Only for used consumer goods in Germany (electronics, furniture, bikes, tools, toys, clothing).
  Real estate, vehicles, jobs, pets and services are not priced. Say so instead of guessing.

HOW TO BUILD THE INPUT
- If the user shares a photo, read the exact product from it: brand, model, generation, storage size,
  edition. Check labels, the box and invoices in the photo. If you cannot tell the exact model, ask
  the user before calling the Actor, because the model decides the price.
- "query" is only the product name, for example "PlayStation 5 Disc Edition", "iPhone 13 128GB",
  "RX 7800 XT". Do not put accessories, "OVP", "mit Controller" or full sentences into it.
- Put the condition into "condition": new (sealed, unopened), like_new (as new, with box),
  good (light wear), used (clear signs of use), worn (heavy wear). With "listingUrl" use "auto".
- Optional: "shippingOnly": true for buying across Germany, "priceMax" / "priceMin" in EUR.
- Set callOptions.maxTotalChargeUsd to 0.5 to cap the cost. One call per item is enough.

HOW TO READ THE RESULT
- Use only numbers from the result. Never invent prices.
- Check "confidence". If it is "low", or there is no recommendation but a "hint", tell the user why
  (the hint says what to refine, for example adding brand and model), refine the query once, and retry.
- If the result has "sealed_new_median", mention it as the price level of sealed brand-new ads.
  The recommended used price is already kept below it.
- These are ASKING prices of comparable ads, not final sale prices. Real sales are usually 5 to 10 %
  lower. Tell the user the asking price, the quick-sale price and the expected range.
- Mention what the photo cannot show and what moves the price by 10 to 20 %: original box, invoice or
  warranty, accessories, battery or health status, storage size.
- For deals: report the verdict (suspiciously_cheap, good_deal, fair_price, overpriced) and the
  suggested offer. For "suspiciously_cheap" warn about scams and defects, and advise paying only
  with buyer protection.
- Answer in the user's language. Prices are in EUR.
```

Short version for a chat message:

```text
Use the Apify Actor beltech/kleinanzeigen-resell-price-checker (call-actor, then get-dataset-items)
to price my used item on Kleinanzeigen. Input: {"action": "estimate_sale_price", "query": "<exact
model>", "condition": "<like_new|good|used|worn>"}. Read the exact model from my photo first and ask
me if unsure. Only use numbers from the result, mention the confidence, and remind me that these are
asking prices, not final sale prices.
```

### What you can do

| Action (`action`) | What you get |
|---|---|
| `estimate_sale_price` | recommended asking price, quick-sale price and expected sale range for a used item |
| `check_deal` | verdict for a price or an ad URL (suspiciously cheap, good deal, fair, overpriced) and a suggested offer |
| `search_listings` | matching listings with deal labels and a market summary |
| `market_stats` | median, quartiles, sample size and confidence for a product |
| `get_listing` | one ad in detail: description, condition, seller type, category |

### When an agent should call it

| The user says | Input |
|---|---|
| "What should I ask for my graphics card?" / "How much is my iPhone 13 worth?" | `{"action": "estimate_sale_price", "query": "iPhone 13 128GB", "condition": "good"}` |
| "Is 400 € a good price for an RTX 3080?" | `{"action": "check_deal", "query": "RTX 3080", "priceEur": 400}` |
| "Is this listing a good deal?" (with a link) | `{"action": "check_deal", "listingUrl": "https://www.kleinanzeigen.de/s-anzeige/..."}` |
| "Find me a used RX 7800 XT under 500 €." | `{"action": "search_listings", "query": "RX 7800 XT", "priceMax": 500}` |
| "What does a used Steam Deck cost right now?" | `{"action": "market_stats", "query": "Steam Deck OLED"}` |

If the user shares a photo, the agent reads the exact model from the photo, label, box or invoice and
passes it as text in `query`. Images are not processed by the Actor itself.

### Call it

**From an AI agent (Apify MCP server).** The agent finds the Actor with `search-actors`, calls it with
`call-actor` using one of the inputs above, and reads the result with `get-dataset-items` using the
returned dataset ID.

**From code or automations (one request, result in the response):**

```bash
curl -X POST "https://api.apify.com/v2/acts/beltech~kleinanzeigen-resell-price-checker/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"action": "estimate_sale_price", "query": "PlayStation 5 Disc Edition", "condition": "like_new"}'
```

**By hand.** Open the Actor, pick an action in the form and click Start.

Every run writes its result to the dataset (export as JSON, CSV or Excel) and the full answer to the
key-value store record `RESULT`. The `summary` field holds one readable sentence.

#### Example: `estimate_sale_price`

```json
{
  "action": "estimate_sale_price",
  "product": "PlayStation 5 Disc Edition",
  "searched_as": "PS5",
  "condition": "like_new",
  "median": 450,
  "p25": 437.5,
  "p75": 542.5,
  "n": 12,
  "confidence": "medium",
  "asking_price_eur": 540,
  "quick_sale_eur": 440,
  "expected_sale_range_eur": [485, 540],
  "basis": "12 comparable listings; condition \"like_new\" priced at the matching point of the 438-542 EUR market range.",
  "summary": "Ask 540 EUR, quick sale 440 EUR (12 matching ads)"
}
```

The full `RESULT` record also contains the 5 closest matching ads as evidence. If the product name is
too generic or too few matching ads exist, there is no recommendation and `hint` says what to refine.
"Sofa" is too generic, "IKEA Kallax 2x4" works.

#### Example: `check_deal`

```json
{
  "action": "check_deal",
  "verdict": "fair_price",
  "price_eur": 520,
  "fair_price_eur": 520,
  "difference_vs_fair_pct": 0.4,
  "cheaper_than_share_of_ads_pct": 52,
  "suggested_offer_eur": 490,
  "summary": "fair_price: In line with the market price. A small discount is usually possible."
}
```

With a `listingUrl` the condition ("Zustand") is read from the ad. Ads marked as defective get no
verdict because they cannot be compared with working items.

#### Input fields

| Field | Used by | Meaning |
|---|---|---|
| `action` | all | one of the actions above (default `search_listings`) |
| `query` | all except `get_listing` | product, ideally brand and model |
| `condition` | `estimate_sale_price`, `check_deal` | `auto`, `new` (sealed), `like_new`, `good`, `used`, `worn` |
| `priceEur` | `check_deal` | the price to judge |
| `listingUrl` | `check_deal`, `get_listing` | link to a kleinanzeigen.de ad |
| `priceMin`, `priceMax`, `shippingOnly`, `maxResults`, `includeVariants` | `search_listings` | filters and size |
| `location`, `radiusKm` | search | local pickup |

### How the price is calculated

1. **Fetch** up to 100 current listings for the search, newest first.
2. **Classify** each listing as the exact product, a variant (for example Super, Ti, Pro Max),
   accessory, bundle (complete PC, laptop, several units), defect, or off topic (swap, wanted, rental).
3. **Calculate** median and quartiles from the exact-product listings only, with outliers removed.
   Ads offering sealed brand-new goods ("NEU & OVP", "ungeöffnet") are kept apart, because their prices
   follow the retail price. A used item is priced from used ads only and never above the sealed-new
   ads; their median is reported as `sealed_new_median`. Use condition `new` to price a sealed item.
4. **Rate confidence:** `high` from 12 listings, `medium` from 6, otherwise `low`. A very wide price
   range or a broad category such as "sofa" also gives `low`, with a note on how to refine the search.
5. **Price bands:** quick sale is the lower quartile, market is the median, ambitious is the upper
   quartile. `estimate_sale_price` picks the point that matches the condition.
6. **Deal labels** (`below_market`, `fair`, `above_market`, `suspiciously_cheap`) appear only when
   there are at least 6 comparable listings.

These are asking prices of similar listings. Final sale prices are usually somewhat lower.

### Pricing

Pay per event, no subscription, no extra platform usage charge. You pay only for results that match
your search.

| Event | Price (USD) | Charged for |
|---|---|---|
| `search_start` | 0.006 | each search |
| `listing_result` | 0.0025 | each returned listing |
| `listing_detail` | 0.008 | `get_listing` |
| `market_stats` | 0.010 | `market_stats` |
| `sale_estimate` | 0.050 | `estimate_sale_price` |
| `deal_check` | 0.030 | `check_deal` |

### Good to know

- Kleinanzeigen.de only. Real estate, vehicles, jobs, pets, services and giveaways are not priced;
  such requests return a short explanation and cost nothing.
- Works best with a specific model ("RX 7800 XT", "iPhone 13 128GB"). Broad terms get a low-confidence result.
- A run takes about 5 to 15 seconds.
- `shipping_only` is applied by this Actor because Kleinanzeigen has no shipping filter in its search.
- Searches with `location` and `radiusKm` can include a few nationwide results when there are only few local ads.
- No sold-price data. Prices are what sellers ask.
- If Kleinanzeigen is unreachable or changes its page layout, the run fails with a clear message and
  you are not charged.

### Data and privacy

The Actor reads publicly visible listing data and does not store personal data. To classify
listings, listing titles and prices (no personal data) are sent to a third-party language model API.
This Actor is not affiliated with or endorsed by Kleinanzeigen. Make sure your use complies with
the terms of the websites you access and with applicable law.

### FAQ

**Do I need a Kleinanzeigen account or API key?** No. You only need an Apify account.

**Why is the confidence low?** The search is too broad, so prices differ too much to give one
meaningful number. Add brand and model.

**Are these the prices items actually sold for?** No. They are asking prices of comparable listings.
Expect final prices to be a bit lower.

**Does it work for Austria or Switzerland?** Not at the moment.

# Actor input Schema

## `action` (type: `string`):

Choose the function to run. Each run bills only the events of that function.

## `query` (type: `string`):

Product name, ideally with brand and model (e.g. "RX 7800 XT", "iPhone 13 128GB"). Used by all actions except "Read one listing". Generic terms like "sofa" give a low-confidence price.

## `maxResults` (type: `integer`):

How many matching listings to return (1-50). You are only billed for returned listings.

## `priceMin` (type: `integer`):

Only listings priced at or above this amount.

## `priceMax` (type: `integer`):

Only listings priced at or below this amount.

## `shippingOnly` (type: `boolean`):

Only listings that offer shipping (nationwide buying).

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

Optional. For local pickup, e.g. "München" or "80331".

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

Search radius around the location. Only used together with a location.

## `includeVariants` (type: `boolean`):

Also return related variants (e.g. RTX 4070 Super/Ti when searching RTX 4070). They never count towards the price statistics.

## `condition` (type: `string`):

Condition of the item. Used by the sell price estimate and the deal check. "Automatic" reads it from the ad when you give a listing URL, otherwise assumes good.

## `priceEur` (type: `number`):

Deal check only: the asking price you want to judge. Not needed if you give a listing URL.

## `listingUrl` (type: `string`):

Deal check or "Read one listing": link to a kleinanzeigen.de ad (.../s-anzeige/...).

## Actor input object example

```json
{
  "action": "search_listings",
  "query": "RX 7800 XT",
  "maxResults": 20,
  "shippingOnly": false,
  "includeVariants": false,
  "condition": "auto"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `market` (type: `string`):

No description

## `result` (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 = {
    "query": "RX 7800 XT"
};

// Run the Actor and wait for it to finish
const run = await client.actor("beltech/kleinanzeigen-resell-price-checker").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 = { "query": "RX 7800 XT" }

# Run the Actor and wait for it to finish
run = client.actor("beltech/kleinanzeigen-resell-price-checker").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 '{
  "query": "RX 7800 XT"
}' |
apify call beltech/kleinanzeigen-resell-price-checker --silent --output-dataset

```

## MCP server setup

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

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/3PhXhXWpJswKS87p5/builds/OeTZNced1bdOilXFp/openapi.json
