# 2dehands Scraper — Belgium Classified Ads & Prices (`logiover/2dehands-belgium-marketplace-scraper`) Actor

Scrape 2dehands.be, the largest classified ads marketplace in Belgium. Extract title and description, price in euros and price type, seller name, city and GPS coordinates, listing date, category and photos across every category.

- **URL**: https://apify.com/logiover/2dehands-belgium-marketplace-scraper.md
- **Developed by:** [Logiover](https://apify.com/logiover) (community)
- **Categories:** E-commerce, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 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

## 2dehands Scraper — Belgium Classified Ads & Prices

Belgium's largest classified ads marketplace in rows: title and description, price in euros and price type, seller, city, GPS coordinates, listing date and photos — across every category.

### What does the 2dehands Scraper do?

This Actor collects classified ads from **2dehands.be**, the largest consumer marketplace in Belgium and the default place Flemish buyers and sellers meet for anything second-hand.

The ads are read from the page's own server state rather than the rendered cards. That gets three things the cards do not show cleanly: the price as an **integer in cents** rather than formatted text, the **price type** — whether the seller wants a fixed price, a minimum bid, or is giving the item away — and the seller's **GPS coordinates**, so geographic analysis needs no geocoding afterwards.

### Who is it for?

- **Second-hand and recommerce platforms** benchmarking Belgian resale prices.
- **Car and bike dealers** tracking private-sale asking prices in their province.
- **Market researchers** measuring supply and pricing in a consumer category.
- **Price-guide and valuation services** building Belgian resale curves.
- **Retail and brand teams** watching the grey and second-hand market for their products.
- **Cross-border traders** comparing Belgian prices against the Dutch market.

### Use cases

- Track asking prices for a car model across Belgium.
- Compare fixed-price against bidding ads to gauge seller confidence.
- Map ad density by city using the coordinates on every row.
- Watch new-listing volume in a category as a demand indicator.
- Build a second-hand price index for consumer electronics.
- Find professional sellers by counting ads per seller name.
- Compare the same category against the Dutch market for arbitrage.

### Why use this 2dehands Scraper?

- **Price as a clean number**, converted from cents, with bidding sentinels filtered out.
- **Price type kept** — FIXED, MIN\_BID and the rest, so a €1 opening bid is not read as a €1 sale.
- **GPS coordinates on every row**, not just a city name.
- **Listing dates converted to ISO**, with the Dutch label preserved alongside. See the FAQ.
- **Thirty ads per page**, fetched several pages at a time.
- **Keyless and login-free.**

### What data can you extract?

One row per ad. Anything the source left blank comes back as `null`.

| Field | Description |
| --- | --- |
| `itemId` | 2dehands item ID |
| `url` | Link to the ad |
| `title` | Ad title |
| `description` | Ad description |
| `price` | Asking price in euros |
| `priceType` | FIXED, MIN\_BID, FAST\_BID, RESERVED, FREE |
| `sellerName` | Seller display name |
| `city` | Seller city |
| `latitude` | Latitude |
| `longitude` | Longitude |
| `publishedAt` | Listing date as ISO |
| `publishedText` | Listing date as the site shows it |
| `imageUrl` | First photo |
| `category` | The category crawled |
| `scrapedAt` | ISO timestamp of collection |

#### Sample output

```json
{
  "itemId": "m2434093236",
  "url": "https://www.2dehands.be/v/auto-s/jaguar/m2434093236-jaguar-f-pace-r-sport",
  "title": "Jaguar F-Pace R-sport",
  "description": "Een klassevolle, krachtige en perfect onderhouden SUV.",
  "price": 23800,
  "priceType": "MIN_BID",
  "sellerName": "bvdv",
  "city": "Retie & Deel Arendonk & Oud-Turnhout",
  "latitude": 51.267067584607,
  "longitude": 5.0767831589577,
  "publishedAt": "2026-08-23",
  "publishedText": "Vandaag",
  "imageUrl": "https://images.2dehands.com/api/v1/hz-twh-pro-listing/images/8a.jpg",
  "category": "auto s",
  "scrapedAt": "2026-08-23T11:29:25.852Z"
}
```

### How to use the 2dehands Scraper

#### Option A — one category

Put a category slug in **Category** — `auto-s`, `fietsen-en-brommers`, `huis-en-inrichting`, `computers-en-software` — set **Maximum results** and run.

#### Option B — several categories

Run once per category and combine the datasets. Each row carries its `category`.

#### Option C — a price watch

Schedule a daily run and diff by `itemId` to see what sold, what was relisted and what changed price.

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `category` | string | `auto-s` | Category slug as it appears in a 2dehands URL after `/l/` |
| `maxResults` | integer | 1000 | Stop after this many ads (max 50,000) |
| `proxyConfiguration` | object | BE residential | 2dehands serves Belgian exits |

### Tips for best results

- **Always read `priceType` next to `price`.** A `MIN_BID` of €50 is an opening bid, not an asking price, and averaging the two together will mislead you.
- **Use the coordinates, not the city string**, for mapping — Belgian municipality names are often compound, as in the sample above.
- **`publishedText` is the audit trail** for `publishedAt`; keep it if you need to justify a date.
- **Take the slug from the URL**: `2dehands.be/l/**fietsen-en-brommers**/`.
- **Deduplicate on `itemId`** when combining scheduled runs; relisted ads keep their id.

### Integrations

Connect the dataset to Make, Zapier, Airbyte, Google Sheets, Slack, GitHub or any HTTP endpoint through Apify integrations, or schedule a run and push results into a warehouse with a webhook.

### API usage

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("logiover/2dehands-belgium-marketplace-scraper").call(run_input={
    "category": "auto-s",
    "maxResults": 3000,
})
rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())
fixed = [r["price"] for r in rows if r["priceType"] == "FIXED" and r["price"]]
print("median fixed price €", sorted(fixed)[len(fixed) // 2])
```

### Use with AI agents (MCP)

The Actor is callable from the Apify MCP server, so an assistant can pull Belgian marketplace ads directly and answer pricing and availability questions.

### FAQ

#### Do I need a 2dehands account or API key?

No. This Actor reads the public listing pages; there is nothing to register.

#### How many ads can one run return?

Up to 50,000 per run, thirty per page. Pages are fetched several at a time, so a few thousand ads take about a minute.

#### Why are there two date columns?

Because 2dehands does not publish a timestamp on the listing card — it publishes a Dutch label such as "Vandaag" (today), "Gisteren" (yesterday) or "20 aug 25". A generic date parser returns nothing for all of those. This Actor converts the label to an ISO date in `publishedAt` and keeps the original wording in `publishedText`.

#### What do the price types mean?

`FIXED` is an asking price, `MIN_BID` an opening bid, `FAST_BID` an auction-style listing, `FREE` a giveaway and `RESERVED` an ad already promised to a buyer. Filter on this before computing any average.

#### Why is price sometimes empty?

Because the ad has no real amount attached — a giveaway or a "make me an offer" listing carries a sentinel value rather than a price, which is left as `null` rather than reported as a figure.

#### Is the site in Dutch or French?

2dehands is the Dutch-language Belgian marketplace; its French-language sibling is a separate site. Titles, descriptions and date labels come back in Dutch.

#### Are the coordinates the exact address?

No. They are the seller's approximate location as the site publishes it, accurate to the municipality rather than the doorstep.

#### Can I export to CSV or Excel?

Yes — every run's dataset exports to JSON, CSV, Excel, XML or JSONL.

#### How fresh is the data?

Each run reads the marketplace live, so results are as current as 2dehands itself.

#### Why did my run return zero ads?

Almost always a category slug that does not exist. Copy it from a 2dehands URL exactly as it appears after `/l/`.

### Is it legal to scrape 2dehands?

2dehands is a public marketplace and this Actor reads only its public listing pages — no accounts, no logins. Ad titles, prices and locations are commercial listings published for public view. Seller display names may be personal, so you remain responsible for how you use the data, including under the GDPR, and for respecting the marketplace's terms in your own jurisdiction.

### Related scrapers

- **Marktplaats Scraper** — the Dutch sibling marketplace.
- **Jofogas Scraper** — Hungary's largest classifieds.
- **Kleinanzeigen Scraper** — German classifieds.
- **Subito Scraper** — Italian classifieds.

# Actor input Schema

## `category` (type: `string`):

Category slug exactly as it appears in a 2dehands URL after /l/, e.g. auto-s, fietsen-en-brommers, huis-en-inrichting, computers-en-software.

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

Stop after this many ads. Each page returns 30.

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

2dehands serves Belgian exits. A Belgian residential proxy is used automatically.

## Actor input object example

```json
{
  "category": "auto-s",
  "maxResults": 1000,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "BE"
  }
}
```

# Actor output Schema

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

Every record collected in this run. Open the Dataset tab to browse, filter or export as JSON, CSV or Excel.

# 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 = {
    "category": "auto-s",
    "maxResults": 1000,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "BE"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/2dehands-belgium-marketplace-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 = {
    "category": "auto-s",
    "maxResults": 1000,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "BE",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("logiover/2dehands-belgium-marketplace-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 '{
  "category": "auto-s",
  "maxResults": 1000,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "BE"
  }
}' |
apify call logiover/2dehands-belgium-marketplace-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,logiover/2dehands-belgium-marketplace-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/KsSTH9ZKqKm2bsb6s/builds/ATfFiqUupoq5x8dyq/openapi.json
