# mobile.de Scraper - Car Listings & Seller Leads (`webdata_labs/mobile-de-car-scraper`) Actor

\[$0.55 / 1K listings] Scrape mobile.de car listings with the seller's phone number, dealer rating and dealer-or-private flag on every row. No start fee.

- **URL**: https://apify.com/webdata\_labs/mobile-de-car-scraper.md
- **Developed by:** [WebData Labs](https://apify.com/webdata_labs) (community)
- **Categories:** E-commerce, Lead generation, Business
- **Stats:** 1 total users, 0 monthly users, 88.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

## mobile.de Scraper — Car Listings & Seller Leads

Scrape Germany's largest vehicle marketplace. Every listing row comes back with the **seller's
phone number**, their **dealer rating**, and whether they are a **dealer or a private owner** —
the fields other mobile.de scrapers make you open each vehicle page to get, or never return at
all.

**$0.55 per 1,000 listings. No start fee.** Cheaper per row than every other mobile.de Actor
on the Store, and the only one that hands you the seller's contact details on the search row
itself.

***

### What you get on every listing row

| Group | Fields |
|---|---|
| Vehicle | `make`, `model`, `variant` (the trim line), `bodyType` |
| Money | `priceEur`, `priceRating` (mobile.de's own "very good / good / fair price" verdict) |
| Specification | `firstRegistration` (ISO `2023-06`), `mileageKm`, `powerKw`, `powerHp`, `fuelType`, `transmission`, `cubicCapacityCcm`, `emissionClass`, `doors`, `seats`, `exteriorColour`, `curbWeightKg`, `previousOwners`, `generalInspection`, `countryVersion` |
| **Seller** | `sellerType` (`DEALER` / `FSBO` / `COMM_FSBO`), `isPrivateSeller`, `sellerPhone`, `sellerPhones`, `sellerRating`, `sellerRatingCount`, `sellerId`, `sellerCity`, `sellerZip`, `sellerCountry` |
| Bookkeeping | `listingId`, `listingUrl`, `imageCount`, `isSponsored`, `searchUrl`, `page`, `position`, `scrapedAt` |

Numbers arrive as numbers: `123.170 km` becomes `123170`, `81 kW (110 PS)` becomes
`powerKw: 81` and `powerHp: 110`, `10/2015` becomes `2015-10`. Sorting and filtering the export
works without cleaning it first.

### Three ways to point it at a market

**1. Paste a search URL.** Filter on mobile.de exactly how you like, copy the address bar,
drop it into `searchUrls`. Everything the site can filter, this Actor can scrape.

**2. Build the search here.** Makes by name (`Volkswagen`, `Porsche`, …), price and mileage
ranges, model year, fuel, gearbox, body type, radius around a point, and the filters that
matter commercially:

- `sellerType: FSBO` — **private sellers only**. These are the cars dealers buy.
- `priceRatings: ["VERY_GOOD_PRICE"]` — mobile.de's own under-market verdict.
- `priceReducedOnly` — sellers who have already dropped the asking price.
- `onlineSinceDays: 1` — listed in the last 24 hours. Schedule it daily and you have a
  new-stock monitor.
- `minSellerRating` — only dealers rated 4 stars and up.

**3. Name specific vehicles or dealers.** `listingUrls` takes vehicle URLs or bare IDs.
`sellerIds` takes the `sellerId` from any row and returns that dealer's entire stock.

### Optional: the vehicle's own page

Turn on `includeVehicleDetails` and each vehicle's page is opened too, adding the full
equipment list, the seller's own description, every photo URL, and the dealer's street
address, opening hours and rating breakdown.

It is billed separately, at $0.012 per detail page, because **one detail page costs as much to
fetch as a whole search page of 24 listings**. Most people never need it: the phone number,
rating and full specification are already on the listing row. It is off by default and capped
by `maxVehicleDetails`.

### Pricing

| Event | Free | Bronze | Silver | Gold+ |
|---|---|---|---|---|
| Listing | $0.55 / 1K | $0.51 / 1K | $0.47 / 1K | **$0.44 / 1K** |
| Vehicle detail page | $12 / 1K | $11.10 / 1K | $10.30 / 1K | **$9.60 / 1K** |

**No start fee** — several competing mobile.de Actors add a per-run charge on top of their
per-row price, which is what makes small runs expensive elsewhere.

### Example output

```json
{
  "itemType": "listing",
  "listingId": 460734741,
  "listingUrl": "https://suchen.mobile.de/fahrzeuge/details.html?id=460734741",
  "make": "Volkswagen",
  "model": "Golf",
  "variant": "1.2 TSI BlueMotion Technology Lounge",
  "priceEur": 9976,
  "priceRating": "REASONABLE_PRICE",
  "firstRegistration": "2015-10",
  "mileageKm": 123170,
  "powerKw": 81,
  "powerHp": 110,
  "fuelType": "Benzin",
  "transmission": "Schaltgetriebe",
  "sellerType": "DEALER",
  "isPrivateSeller": false,
  "sellerPhone": "+4923029606510",
  "sellerRating": 4.2,
  "sellerRatingCount": 18,
  "sellerId": 452930,
  "sellerCity": "Witten",
  "sellerZip": "58453"
}
```

### What people use it for

- **Dealer lead lists.** Filter to `DEALER`, and every row is a dealership with a phone
  number, a star rating, a postcode and the stock they are currently carrying.
- **Sourcing stock.** `sellerType: FSBO` plus `priceRatings: VERY_GOOD_PRICE` plus a radius is
  a standing list of under-priced private-sale cars near you.
- **Price monitoring.** Re-run the same search on a schedule and diff `priceEur` by
  `listingId` to see who cut prices and by how much.
- **Market and residual-value analysis.** Mileage, first registration, power and price for
  thousands of comparable cars, already typed as numbers.
- **Competitor stock tracking.** `sellerIds` returns one dealer's whole inventory.

### Honest limits

- **mobile.de refuses ordinary traffic.** It answers only through a heavy unblocking proxy, so
  a page takes roughly 20-45 seconds and about one request in two has to be retried. A run of
  a few hundred listings takes minutes, not seconds. This is the source, not the Actor — and
  it is why the per-row price is what it is.
- Occasionally a search page cannot be unblocked at all within four attempts. The Actor logs
  it, keeps the rows it already has, and carries on; re-running usually gets through.
- **Phone numbers are the ones sellers publish on their own listings.** Some listings have
  none, and some have several (the array is in `sellerPhones`). Nothing here is behind a
  login, and no personal data beyond what mobile.de shows publicly is collected.
- **Field values are German**, as filed: `Benzin`, `Schaltgetriebe`, `Limousine`. Enum-style
  fields (`sellerType`, `priceRating`, `emissionClass`) are language-neutral codes.
- mobile.de lists vehicles across Europe but the site and its data are German; `sellerCountry`
  tells you where each car actually is.
- A listing can be withdrawn between the search page and the detail page. Those are skipped.
- `variant` comes from the visible card; on a page whose layout mobile.de has changed, it can
  be empty while every other field still fills.

### Tips

- Start with `maxListings: 100` to see the shape of the data, then raise it.
- Sorting by `newestListing` plus `onlineSinceDays: 1` is the cheapest way to watch a market.
- `sellerId` is the join key: group rows by it to turn a listing scrape into a dealer list.
- Deep pagination works — searches have been read past page 100 — so a large market is
  reachable in one run if you give it time.

# Actor input Schema

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

Open mobile.de, filter exactly how you want, then paste the URL of the results page here. This is the most precise way to search and it overrides the filters below. Leave empty to build the search from the fields underneath.

## `makes` (type: `array`):

Car makes by name, e.g. Volkswagen, BMW, Porsche. Each make is searched separately. Ignored when search URLs are given.

## `modelDescription` (type: `string`):

Free text matched against the model and trim line, e.g. "Golf GTI". Works together with Makes.

## `maxListings` (type: `integer`):

How many listing rows to return in total, across all searches. mobile.de serves 20-24 per page.

## `vehicleCategory` (type: `string`):

Which mobile.de marketplace to search.

## `priceMinEur` (type: `integer`):

Lowest asking price to include.

## `priceMaxEur` (type: `integer`):

Highest asking price to include.

## `firstRegistrationFrom` (type: `integer`):

Oldest model year to include, e.g. 2020.

## `firstRegistrationTo` (type: `integer`):

Newest model year to include.

## `mileageMaxKm` (type: `integer`):

Highest odometer reading to include.

## `powerMinKw` (type: `integer`):

Lowest engine power to include. 1 kW is about 1.36 hp.

## `fuelTypes` (type: `array`):

Leave empty for any fuel.

## `transmissions` (type: `array`):

Leave empty for any gearbox.

## `bodyTypes` (type: `array`):

Car body styles. Leave empty for any.

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

New or used vehicles only.

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

Dealers, private sellers, or company-owned vehicles. Private sellers are the ones dealers buy from.

## `minSellerRating` (type: `string`):

Only dealers rated at least this many stars. mobile.de offers 3, 4 and 5 only.

## `priceRatings` (type: `array`):

mobile.de's own verdict on whether a car is priced below the market. The shortcut to under-priced stock.

## `priceReducedOnly` (type: `boolean`):

Sellers who have already dropped the price are the ones willing to negotiate.

## `onlineSinceDays` (type: `string`):

Only listings published recently. Set to 1 day and schedule the run daily to watch a market for new stock.

## `excludeDamaged` (type: `boolean`):

Leave on to skip accident and repair projects.

## `centerLatLon` (type: `string`):

Centre of a radius search as "latitude,longitude", e.g. 52.52,13.405 for Berlin. Use with Radius.

## `radiusKm` (type: `string`):

How far from the centre point to search. mobile.de offers these steps only.

## `sellerIds` (type: `array`):

Scrape one dealer's whole stock. The ID is the sellerId field on any row from that dealer.

## `fullTextQuery` (type: `string`):

Free text matched against the seller's description text, e.g. "Standheizung".

## `sortBy` (type: `string`):

Which results come first.

## `includeVehicleDetails` (type: `boolean`):

Adds the full equipment list, the seller's description, all photo URLs and the dealer's street address and opening hours. Slower, and billed per detail page.

## `maxVehicleDetails` (type: `integer`):

Cap on how many detail pages to open, so a wide search cannot run up a bill.

## `listingUrls` (type: `array`):

Scrape specific vehicles directly. Paste mobile.de details.html URLs or bare listing IDs.

## Actor input object example

```json
{
  "searchUrls": [
    "https://suchen.mobile.de/fahrzeuge/search.html?dam=false&isSearchRequest=true&ms=25200%3B%3B%3B&ref=srp&sb=rel&vc=Car"
  ],
  "makes": [
    "Volkswagen"
  ],
  "maxListings": 100,
  "vehicleCategory": "Car",
  "priceReducedOnly": false,
  "excludeDamaged": true,
  "sortBy": "relevance",
  "includeVehicleDetails": false,
  "maxVehicleDetails": 25
}
```

# Actor output Schema

## `listings` (type: `string`):

One row per vehicle, with price, specification and the seller's contact details.

## `sellerLeads` (type: `string`):

The same rows reduced to who is selling: phone, rating, location and dealer-vs-private.

## `vehicleDetails` (type: `string`):

Full equipment lists, photos and dealer addresses, when detail pages were requested.

## `summary` (type: `string`):

Counts, the searches that ran, and how many requests mobile.de refused.

# 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 = {
    "searchUrls": [
        "https://suchen.mobile.de/fahrzeuge/search.html?dam=false&isSearchRequest=true&ms=25200%3B%3B%3B&ref=srp&sb=rel&vc=Car"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("webdata_labs/mobile-de-car-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 = { "searchUrls": ["https://suchen.mobile.de/fahrzeuge/search.html?dam=false&isSearchRequest=true&ms=25200%3B%3B%3B&ref=srp&sb=rel&vc=Car"] }

# Run the Actor and wait for it to finish
run = client.actor("webdata_labs/mobile-de-car-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 '{
  "searchUrls": [
    "https://suchen.mobile.de/fahrzeuge/search.html?dam=false&isSearchRequest=true&ms=25200%3B%3B%3B&ref=srp&sb=rel&vc=Car"
  ]
}' |
apify call webdata_labs/mobile-de-car-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,webdata_labs/mobile-de-car-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/GuPsyWEqWV6ATZfTe/builds/TF1YlslrNzQARBoff/openapi.json
