# Mobile.de Scraper — Vehicle Inventory Monitor (`khadinakbar/mobile-de-scraper`) Actor

Scrape public Mobile.de vehicle listings from search or listing URLs. Get prices, mileage, specs, sellers, images, and monitored inventory price changes.

- **URL**: https://apify.com/khadinakbar/mobile-de-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** E-commerce, Automation, MCP servers
- **Stats:** 1 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 vehicle listing returneds

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/platform/actors/running/actors-in-store#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

## Mobile.de Scraper — Vehicle Inventory Monitor

Use this Apify Actor to collect public Mobile.de vehicle listings from a search URL or a listing URL, and to monitor repeated runs for inventory price changes when you supply a stable monitoring key. Each dataset record represents one vehicle listing, so a single row captures one vehicle and its public listing context. Useful fields include listing URL, title, make, model, price, mileage, first registration, fuel type, transmission, power, seller information, image URLs, change type, previous price, source search URL, scrape timestamp, and parse warnings. The actor is usable through Apify MCP and writes normalized records to the default dataset for exports, analysis, and agent workflows.

### Best fit and connected workflows

This Actor fits workflows that begin with a Mobile.de results page or a direct listing page and need structured vehicle inventory data for a spreadsheet, warehouse, dashboard, or AI agent. It routes naturally into:

- inventory snapshots from public Mobile.de search URLs
- repeated monitoring of the same search with `monitoringKey`
- price-change tracking with `changesOnly`
- concise exports for agents that need compact vehicle records
- detailed exports when description, equipment, more images, and public phone data are useful

The input keeps the source context on Mobile.de itself, then passes that exact URL into the Actor so the returned record preserves the same search or listing context in `sourceSearchUrl`.

### Focused standalone workflow

This Actor is designed as a focused standalone workflow.

#### Practical scenario

A used-car analyst opens a Berlin-focused Mobile.de search result page for BMW estates, copies the URL, and runs the Actor with `includeDetails: true` and a stable `monitoringKey`. The returned record includes `priceEur`, `mileageKm`, `firstRegistration`, `sellerName`, `changeType`, and `previousPriceEur`. If the record is marked `price_changed`, the analyst updates a tracking sheet and schedules the same search URL for the next run.

### Input fields

| Field | Type | Purpose |
| --- | --- | --- |
| `dataSource` | string | Selects `browser` for public Mobile.de pages or `officialApi` when the owner has configured authorized Mobile.de Search API access. |
| `startUrls` | array | One or more Mobile.de results or listing URLs for the selected source. Required. |
| `maxResults` | integer | Maximum number of vehicle records written to the dataset. Range 1 to 500. |
| `includeDetails` | boolean | Adds listing descriptions, equipment, extra images, and seller fields when detail pages are fetched successfully. |
| `responseFormat` | string | Chooses `concise` or `detailed` record content. Core vehicle fields remain available in both. |
| `monitoringKey` | string | Stable label for repeated runs of the same search. Enables comparison with prior runs using the same key. |
| `changesOnly` | boolean | Returns only new or price-changed listings when used with a monitoring key. |
| `proxyCountry` | string | Selects the residential browser session country in browser mode. Supported values: `DE`, `AT`, `BE`, `CH`, `FR`, `NL`. |

#### Focused JSON input example

```json
{
  "startUrls": [
    {
      "url": "https://suchen.mobile.de/auto/gebrauchtwagen.html"
    }
  ],
  "dataSource": "browser",
  "maxResults": 25,
  "includeDetails": true,
  "responseFormat": "concise",
  "monitoringKey": "berlin-bmw-inventory",
  "changesOnly": false,
  "proxyCountry": "DE"
}
```

### Output fields

Each dataset item is one normalized vehicle record.

| Field | Type | Meaning |
| --- | --- | --- |
| `listingId` | string | Stable Mobile.de listing identifier extracted from the listing URL. |
| `listingUrl` | string | Canonical public URL for the vehicle listing. |
| `title` | string | Vehicle title shown on Mobile.de. |
| `make` | string or null | First title token used as a available vehicle make. |
| `model` | string or null | Remaining title text after the available make. |
| `priceEur` | number or null | Advertised price in euros. |
| `currency` | string or null | ISO currency code for the advertised price. |
| `firstRegistration` | string or null | First registration month and year. |
| `mileageKm` | number or null | Advertised mileage in kilometers. |
| `fuelType` | string or null | Publicly listed fuel or drive type. |
| `transmission` | string or null | Publicly listed transmission type. |
| `powerKw` | number or null | Publicly listed engine power in kilowatts. |
| `bodyType` | string or null | Publicly listed body style when detected. |
| `vehicleCondition` | string or null | Publicly listed condition when detected. |
| `location` | string or null | Public seller or dealer location text. |
| `postalCode` | string or null | Postal code extracted from the public location text when available. |
| `sellerName` | string or null | Public seller or dealer name when shown. |
| `sellerType` | string or null | Public seller classification when shown. |
| `sellerPhone` | string or null | Public phone number when exposed by Mobile.de and detailed output is selected. |
| `description` | string or null | Public listing description when detailed output is selected. |
| `equipment` | array | Public vehicle equipment entries when detailed output is selected. |
| `imageUrls` | array | Public vehicle image URLs; concise mode returns the primary image where available. |
| `listingDate` | string or null | Public listing date when Mobile.de exposes it. |
| `changeType` | string | Inventory comparison status: `new`, `price_changed`, `unchanged`, or `unknown`. |
| `previousPriceEur` | number or null | Prior price for changed listings when monitoring is enabled. |
| `sourceSearchUrl` | string | Source search or listing URL used for the record. |
| `scrapedAt` | string | ISO 8601 extraction timestamp. |
| `parseWarnings` | array | Non-fatal extraction warnings for the record. |

#### Illustrative output record

```json
{
  "listingId": "1001",
  "listingUrl": "https://suchen.mobile.de/fahrzeuge/details.html?id=1001",
  "title": "BMW 320d Touring",
  "make": "BMW",
  "model": "320d Touring",
  "priceEur": 23490,
  "currency": "EUR",
  "firstRegistration": "03/2021",
  "mileageKm": 71200,
  "fuelType": "Diesel",
  "transmission": "Automatic",
  "powerKw": 140,
  "bodyType": "Estate",
  "vehicleCondition": "Used",
  "location": "10115 Berlin",
  "postalCode": "10115",
  "sellerName": "Example Autohaus GmbH",
  "sellerType": "Dealer",
  "sellerPhone": "+49 30 123456",
  "description": "Well-maintained estate car.",
  "equipment": [
    "Navigation system",
    "Parking sensors"
  ],
  "imageUrls": [
    "https://images.example.test/car.jpg"
  ],
  "listingDate": "2026-07-14",
  "changeType": "price_changed",
  "previousPriceEur": 24990,
  "sourceSearchUrl": "https://suchen.mobile.de/auto/gebrauchtwagen.html",
  "scrapedAt": "2026-07-14T12:00:00.000Z",
  "parseWarnings": []
}
```

### How it works

This Actor accepts Mobile.de results or listing URLs and writes normalized vehicle records to the default dataset. In browser mode, it uses an actor-managed residential browser session with the selected proxy country. In `officialApi` mode, it uses the authorized Mobile.de Search API path configured by the actor owner. The input controls how many records are written, whether detail pages are fetched, how much optional text is included, and whether repeated runs are compared with prior runs for the same `monitoringKey`.

The dataset schema keeps the core vehicle fields stable across runs. Monitoring runs set `changeType` to `new`, `price_changed`, `unchanged`, or `unknown`, and `previousPriceEur` is populated when a tracked listing changes.

### Pricing

This actor uses Pay per event plus Apify platform usage. Event charges are based on actor memory at startup, each validated vehicle record written to the dataset, and each successfully enriched detail page. Apify compute and any platform usage are billed separately. For current live pricing, check the Pricing tab on the Actor page.

For example, a run that returns twenty-five vehicle listings charges twenty-five `Vehicle listing returned` events, plus one `Actor start` event, and may also include `Vehicle details enriched` events when detail pages are fetched successfully. The total depends on the live pricing shown in Apify and on the selected input.

### Use with AI agents (MCP)

This Actor is available through Apify MCP as a compact Mobile.de inventory tool for search URLs and listing URLs.

**Tool description:** collect one-record-per-listing Mobile.de inventory data with stable vehicle fields, optional detail enrichment, and monitoring-aware change tracking.

The exact Actor identity is `khadinakbar/mobile-de-scraper`.

> "Use the Actor `khadinakbar/mobile-de-scraper` with this Mobile.de search URL, return up to 25 vehicle listings, include details, and keep the output compact for downstream analysis. Then read the dataset items and summarize any records where `changeType` is `price_changed`."

Output interpretation for agents:

- `listingUrl`, `title`, `priceEur`, `mileageKm`, and `sellerName` identify each vehicle.
- `changeType` and `previousPriceEur` indicate monitored inventory movement.
- `sourceSearchUrl` preserves provenance back to the original Mobile.de page.
- `parseWarnings` can signal that some public fields were only partially extracted.
- Pagination is controlled by `maxResults`, which bounds the number of listing records written.
- Cost guidance is event-based: one listing record maps to one charged `Vehicle listing returned` event, and optional detail enrichment adds `Vehicle details enriched` events when fetched successfully. Apify platform usage is separate.

### Apify API example

JavaScript:

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

const run = await client.actor('khadinakbar/mobile-de-scraper').call({
  startUrls: [{ url: 'https://suchen.mobile.de/auto/gebrauchtwagen.html' }],
  maxResults: 25,
  includeDetails: true,
  responseFormat: 'concise',
  monitoringKey: 'berlin-bmw-inventory',
  changesOnly: false,
  proxyCountry: 'DE',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Python:

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run = client.actor("khadinakbar/mobile-de-scraper").call(run_input={
    "startUrls": [{"url": "https://suchen.mobile.de/auto/gebrauchtwagen.html"}],
    "maxResults": 25,
    "includeDetails": True,
    "responseFormat": "concise",
    "monitoringKey": "berlin-bmw-inventory",
    "changesOnly": False,
    "proxyCountry": "DE",
})

items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Best results and outcome guidance

Use a Mobile.de results URL that already contains the filters you want, since the Actor reads the page context from the URL itself. Reuse the same `monitoringKey` with the same search URL when you want comparisons across runs. Keep `maxResults` aligned with the number of listings you actually need, and choose `includeDetails: false` only when the core search-card fields are enough for your workflow. `responseFormat: concise` keeps records compact for agents, while `detailed` adds more public text and media fields.

### Design note

I found that the dataset contract always requires `listingId`, `listingUrl`, `title`, `priceEur`, `currency`, `sourceSearchUrl`, and `scrapedAt`, which makes each record traceable back to the source page and a single extraction moment.

### FAQ

**How should I choose between `browser` and `officialApi`?**\
Use `browser` for public Mobile.de results or listing URLs. Use `officialApi` only when the actor owner has configured authorized Mobile.de Search API access for the documented search or ad URL path.

**What makes one dataset row equal to one vehicle?**\
The output contract defines each item as one normalized vehicle listing, and the dataset schema requires a single `listingId` and `listingUrl` per row.

**How does monitoring work across runs?**\
Provide the same `monitoringKey` and the same search URL on later runs. The Actor compares the current result set with the previous run for that key and sets `changeType` accordingly.

**What fields are most useful for filtering inventory changes?**\
`priceEur`, `previousPriceEur`, `changeType`, `mileageKm`, `firstRegistration`, `fuelType`, `sellerType`, and `location` are useful for prioritizing vehicles.

**Can an AI agent read the output directly?**\
Yes. The dataset contains normalized records, and the `OUTPUT` and `RUN_SUMMARY` key-value records provide run-level outcome and billing information for orchestration.

### Responsible use

Use this Actor for lawful collection and processing of public Mobile.de data. Review the Mobile.de terms, the relevant data-protection obligations, and any downstream sharing rules that apply to your use case and jurisdiction. Public seller information should be handled with appropriate care in sales, enrichment, and monitoring workflows.

# Actor input Schema

## `dataSource` (type: `string`):

Use this to choose the authorized retrieval path. Choose browser for a public Mobile.de results or listing URL, or officialApi only when the actor owner has configured authorized Mobile.de Search API credentials. It defaults to browser and never falls back between modes. This is not a way to supply credentials in the input.

## `startUrls` (type: `array`):

Use this when you already have a Mobile.de URL for the selected data source. In browser mode pass a public results or listing URL such as {"url":"https://suchen.mobile.de/auto/gebrauchtwagen.html"}; in officialApi mode pass only a documented services.mobile.de Search API search or ad URL. At least one valid URL is required and the advanced-search form is not a result page. This is not a free-text vehicle query and it does not accept URLs from other marketplaces.

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

Use this to set the maximum number of vehicle records written to the dataset. Enter an integer such as 25. It defaults to 25 and accepts 1 through 500. This is not a page count; the actor stops before charging more listing events than this limit.

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

Use this when you need listing descriptions, equipment, extra images, and seller fields in addition to search-card data. Set true or false, for example true. It defaults to true and detail enrichment is billed only after a detail page is fetched successfully. This is not required for a fast price-and-mileage-only search export.

## `responseFormat` (type: `string`):

Use this to choose the amount of optional text and media included in each vehicle record. Choose concise or detailed, for example concise. It defaults to concise so AI agents receive compact records, while detailed adds description, equipment, more images, and public phone data when available. This does not change the core price, mileage, registration, and seller fields.

## `monitoringKey` (type: `string`):

Use this when repeated runs should compare a specific Mobile.de search over time. Enter a stable label such as berlin-bmw-inventory. It is optional and creates state only for the same key, with lowercase letters, numbers, and hyphens retained. This is not a Mobile.de seller ID or a dataset ID.

## `changesOnly` (type: `boolean`):

Use this when a scheduled inventory-monitoring run should omit listings whose price did not change. Set true only with a monitoring key, for example true. It defaults to false so an initial run returns all matching vehicles. This does not detect removed ads because Mobile.de result coverage can vary by search and region.

## `proxyCountry` (type: `string`):

Use this to select the country for the actor-managed residential browser session. Choose a supported ISO code such as DE. It defaults to DE; AT, BE, CH, FR, and NL are also supported for regional results. This setting is ignored in officialApi mode and is not a vehicle location filter, which belongs in the selected source URL itself.

## Actor input object example

```json
{
  "dataSource": "browser",
  "startUrls": [
    {
      "url": "https://suchen.mobile.de/auto/gebrauchtwagen.html"
    }
  ],
  "maxResults": 25,
  "includeDetails": true,
  "responseFormat": "concise",
  "monitoringKey": "berlin-bmw-inventory",
  "changesOnly": false,
  "proxyCountry": "DE"
}
```

# Actor output Schema

## `vehicleListings` (type: `string`):

Normalized public Mobile.de vehicle listings returned by this run.

## `output` (type: `string`):

Compact outcome, counts, warnings, and charged event totals.

## `runSummary` (type: `string`):

Detailed diagnostics, source coverage, and billing information for this run.

# 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 = {
    "dataSource": "browser",
    "startUrls": [
        {
            "url": "https://suchen.mobile.de/auto/gebrauchtwagen.html"
        }
    ],
    "maxResults": 1,
    "includeDetails": false,
    "responseFormat": "concise",
    "changesOnly": false,
    "proxyCountry": "DE"
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/mobile-de-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 = {
    "dataSource": "browser",
    "startUrls": [{ "url": "https://suchen.mobile.de/auto/gebrauchtwagen.html" }],
    "maxResults": 1,
    "includeDetails": False,
    "responseFormat": "concise",
    "changesOnly": False,
    "proxyCountry": "DE",
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/mobile-de-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "dataSource": "browser",
  "startUrls": [
    {
      "url": "https://suchen.mobile.de/auto/gebrauchtwagen.html"
    }
  ],
  "maxResults": 1,
  "includeDetails": false,
  "responseFormat": "concise",
  "changesOnly": false,
  "proxyCountry": "DE"
}' |
apify call khadinakbar/mobile-de-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=khadinakbar/mobile-de-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/xakzi9NBYvhUbkpap/builds/MYWUdSnaXFSwvWY9r/openapi.json
