Install

Search used cars on mobile.de by make, price, year and mileage.

Searches mobile.de, Germany's largest car marketplace, like the site's own result list: title, price (and whether negotiable), mobile.de's price rating, first registration, mileage, power, fuel, dealer or private seller, location and link. Sponsored listings are dropped by default. Runs only in the user's browser: mobile.de's Akamai protection rejects non-browser clients.

No reports yetRead-only, no login
Site
mobile.de, Germany
Version
v2 of 2
Runs, last 7 days
No reports yet
sha256
34b10c2a189e…

Requests

sent from your browser, in order
  1. 1GET/fahrzeuge/search.html?fr&isSearchRequest&ml&ms&od&p&s&sb&vcServer-rendered result page (Next.js app router). site.start_path opens a result page with isSearchRequest=true: suchen.mobile.de/ and the bare /fahrzeuge/search.html both redirect to www.mobile.de (seen 2026-11-07 ~13:30). The assert makes a page without listing cards (interstitial, challenge) fail instead of returning an empty list; a real zero-result page shows '>0 Angebote<'. The one-item foreach maps the make to mobile.de's id and builds the range params.repeats, max 1

Parameters

from your agent
include_sponsoredboolean = false
makeenumrequiredCar make "Alfa Romeo" | "Audi" | "BMW" | "BYD" | "Citroën" | "Cupra" | "DS Automobiles" | "Dacia" | "Fiat" | "Ford" | "Honda" | "Hyundai" | "Jaguar" | "Jeep" | "Kia" | "Land Rover" | "Lexus" | "MG" | "MINI" | "Mazda" | "Mercedes-Benz" | "Mitsubishi" | "Nissan" | "Opel" | "Peugeot" | "Polestar" | "Porsche" | "Renault" | "Seat" | "Skoda" | "Smart" | "Subaru" | "Suzuki" | "Tesla" | "Toyota" | "Volkswagen" | "Volvo" | "VW" | "Mercedes" | "Citroen"
max_kmintegerMaximum mileage
price_frominteger
price_tointegerEUR
sortenum "relevance" | "price_asc" | "price_desc" = "relevance"
year_fromintegerFirst registration from this year

Returns

to your agent
carsobject[]accident, damaged, first_registration, fuel, location, mileage_km, negotiable, power, price_eur, price_rating, roadworthy, seller, seller_type, sponsored, title, url
currencyany
makestring
totalintegerAll matching offers on mobile.de

Where it can send

  • suchen.mobile.de

Anything else is blocked by the extension.

Reads from your session

Nothing. Your browser attaches the site's cookies by itself.

Used only in requests to the addresses on the left. Never sent to wield.run or your agent.

Checks

a run passes when
  • length(output.cars) > `10`
  • length(output.cars[?price_eur > `15000` || price_eur < `5000`]) == `0`
  • length(output.cars[?first_registration != `null` && to_number(split(first_registration, '-')[0]) < `2018`]) == `0`
  • length(output.cars[?mileage_km > `100000`]) == `0`
  • length(output.cars[?sponsored]) == `0`
  • starts_with(output.cars[0].url, 'https://suchen.mobile.de/fahrzeuge/details.html?id=')

Raw recipe

Served as canonical JSON from /api/v1/recipes/mobile.de/search-cars, so its sha256 matches the ETag and the index.

Check it yourself
curl -s https://wield.run/api/v1/recipes/mobile.de/search-cars | shasum -a 256
# 34b10c2a189e2366d04d4a66944fa217db4585b183347565eef04cf50e8880c6
mobile.de/search-cars.json, v2
{
  "description": "Searches mobile.de, Germany's largest car marketplace, like the site's own result list: title, price (and whether negotiable), mobile.de's price rating, first registration, mileage, power, fuel, dealer or private seller, location and link. Sponsored listings are dropped by default. Runs only in the user's browser: mobile.de's Akamai protection rejects non-browser clients.",
  "effect": "read",
  "id": "mobile.de/search-cars",
  "keywords": [
    "mobile.de",
    "mobile",
    "auto",
    "gebrauchtwagen",
    "autokauf",
    "pkw",
    "fahrzeugsuche",
    "used car",
    "car marketplace",
    "buy a car",
    "germany cars"
  ],
  "output": {
    "schema": {
      "properties": {
        "cars": {
          "items": {
            "properties": {
              "accident": {
                "description": "Listed as Unfallfahrzeug",
                "type": "boolean"
              },
              "damaged": {
                "description": "Listed as Beschädigt",
                "type": "boolean"
              },
              "first_registration": {
                "description": "YYYY-MM",
                "type": [
                  "string",
                  "null"
                ]
              },
              "fuel": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "location": {
                "description": "Postcode and town",
                "type": [
                  "string",
                  "null"
                ]
              },
              "mileage_km": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "negotiable": {
                "description": "Verhandlungsbasis",
                "type": "boolean"
              },
              "power": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "price_eur": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "price_rating": {
                "description": "mobile.de price rating; null = not rated",
                "enum": [
                  "very_good",
                  "good",
                  "fair",
                  "increased",
                  "high",
                  null
                ]
              },
              "roadworthy": {
                "description": "false when listed as Nicht fahrtauglich",
                "type": "boolean"
              },
              "seller": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "seller_type": {
                "enum": [
                  "dealer",
                  "private"
                ]
              },
              "sponsored": {
                "type": "boolean"
              },
              "title": {
                "type": "string"
              },
              "url": {
                "format": "uri",
                "type": "string"
              }
            },
            "type": "object"
          },
          "type": "array"
        },
        "currency": {
          "const": "EUR"
        },
        "make": {
          "type": "string"
        },
        "total": {
          "description": "All matching offers on mobile.de",
          "type": [
            "integer",
            "null"
          ]
        }
      },
      "required": [
        "make",
        "cars"
      ],
      "type": "object"
    },
    "value": "let $sp = params.include_sponsored, $tt = steps.search[0].total_text || '' in {make: params.make, currency: 'EUR', total: ends_with($tt, ' Angebote') && to_number(replace(replace($tt, ' Angebote', ''), '.', '')) || `null`, cars: steps.search[0].cars[?title != `null` && ($sp || sponsored == `null`)].let $tok = split(details || '', ' • ') in {title: title, price_eur: price_text && to_number(replace(replace(split(trim(price_text), ' ')[0], '.', ''), ',', '.')) || `null`, negotiable: negotiable != `null`, price_rating: contains(price_section || '', 'Sehr guter Preis') && 'very_good' || (contains(price_section || '', 'Guter Preis') && 'good' || (contains(price_section || '', 'Fairer Preis') && 'fair' || (contains(price_section || '', 'Erhöhter Preis') && 'increased' || (contains(price_section || '', 'Hoher Preis') && 'high' || `null`)))), first_registration: ($tok[?starts_with(@, 'EZ ')] | [0]) && join('-', reverse(split(replace(($tok[?starts_with(@, 'EZ ')] | [0]), 'EZ ', ''), '/'))) || `null`, mileage_km: ($tok[?ends_with(@, ' km')] | [0]) && to_number(replace(replace(($tok[?ends_with(@, ' km')] | [0]), ' km', ''), '.', '')) || `null`, power: ($tok[?contains(@, 'kW')] | [0]) || `null`, fuel: ($tok[?contains(`[\"Benzin\",\"Diesel\",\"Elektro\",\"Hybrid (Benzin/Elektro)\",\"Hybrid (Diesel/Elektro)\",\"Autogas (LPG)\",\"Erdgas (CNG)\",\"Wasserstoff\",\"Ethanol (FFV, E85 etc.)\",\"Andere\"]`, @)] | [0]) || `null`, damaged: contains($tok, 'Beschädigt'), accident: contains($tok, 'Unfallfahrzeug'), roadworthy: !contains($tok, 'Nicht fahrtauglich'), seller: seller_name, seller_type: seller_name == 'Privatanbieter' && 'private' || 'dealer', location: seller_location, sponsored: sponsored != `null`, url: split(href, '&')[0]}}"
  },
  "params": {
    "additionalProperties": false,
    "properties": {
      "include_sponsored": {
        "default": false,
        "type": "boolean"
      },
      "make": {
        "description": "Car make",
        "enum": [
          "Alfa Romeo",
          "Audi",
          "BMW",
          "BYD",
          "Citroën",
          "Cupra",
          "DS Automobiles",
          "Dacia",
          "Fiat",
          "Ford",
          "Honda",
          "Hyundai",
          "Jaguar",
          "Jeep",
          "Kia",
          "Land Rover",
          "Lexus",
          "MG",
          "MINI",
          "Mazda",
          "Mercedes-Benz",
          "Mitsubishi",
          "Nissan",
          "Opel",
          "Peugeot",
          "Polestar",
          "Porsche",
          "Renault",
          "Seat",
          "Skoda",
          "Smart",
          "Subaru",
          "Suzuki",
          "Tesla",
          "Toyota",
          "Volkswagen",
          "Volvo",
          "VW",
          "Mercedes",
          "Citroen"
        ],
        "type": "string"
      },
      "max_km": {
        "description": "Maximum mileage",
        "minimum": 1,
        "type": "integer"
      },
      "price_from": {
        "minimum": 0,
        "type": "integer"
      },
      "price_to": {
        "description": "EUR",
        "minimum": 1,
        "type": "integer"
      },
      "sort": {
        "default": "relevance",
        "enum": [
          "relevance",
          "price_asc",
          "price_desc"
        ],
        "type": "string"
      },
      "year_from": {
        "description": "First registration from this year",
        "maximum": 2030,
        "minimum": 1950,
        "type": "integer"
      }
    },
    "required": [
      "make"
    ],
    "type": "object"
  },
  "provenance": {
    "method": "browser-inspect",
    "notes": "spikes/mobile-de.md. curl gets 403 (Akamai); in a browser tab the result page renders 24 listing <article>s with data-testid hooks (listing-title-card-view, price-label, price-negotiable, listing-details-attributes 'EZ 11/1998 • 233.749 km • 37 kW (50 PS) • Benzin', seller-info, sponsored-badge). Params: ms=<makeId>;;; (ids from the page's make filter), p=min:max, sb=p + od=up (verified, cheapest first); fr=year: and ml=:km verified in-page (VW 5,000-15,000 €, from 2018, ≤100,000 km: prices ascending from 5,190 €, all EZ ≥ 2018). The attribute line may start with condition words (Beschädigt, Unfallfahrzeug, Nicht fahrtauglich). Needs site.start_path (contracts ed69d21) because https://suchen.mobile.de/ redirects to www. v2 (2026-11-07): start_path now carries isSearchRequest=true&vc=Car because the bare search path redirects to www.mobile.de (the cause of C5's tab_error); an empty card list now fails the step (C5's q1 returned 200 HTML with 0 cars, so the extension did not retry). Verified in-page on suchen.mobile.de: C5 q1 (VW 5-15k, from 2018, ≤100k km, cheapest) 24 cards/4 sponsored; q2 (BMW ≤20k) 24/4; zero-result page has '>0 Angebote<'. v1 pinned in search-cars.v1.json.",
    "recorded_at": "2026-11-07T12:46:00+01:00",
    "recorded_by": "C4"
  },
  "requires_login": false,
  "schema": "https://wield.run/schema/recipe/v1.json",
  "site": {
    "country": "DE",
    "id": "mobile.de",
    "language": "de",
    "login_url": "https://www.mobile.de/api/auth/login",
    "name": "mobile.de",
    "origin": "https://suchen.mobile.de",
    "origins": [
      "https://suchen.mobile.de"
    ],
    "start_path": "/fahrzeuge/search.html?isSearchRequest=true&vc=Car"
  },
  "steps": [
    {
      "description": "Server-rendered result page (Next.js app router). site.start_path opens a result page with isSearchRequest=true: suchen.mobile.de/ and the bare /fahrzeuge/search.html both redirect to www.mobile.de (seen 2026-11-07 ~13:30). The assert makes a page without listing cards (interstitial, challenge) fail instead of returning an empty list; a real zero-result page shows '>0 Angebote<'. The one-item foreach maps the make to mobile.de's id and builds the range params.",
      "expect": {
        "assert": "contains(body, 'listing-title-card-view') || contains(body, '>0 Angebote<')",
        "content_type": "html",
        "status": [
          200
        ]
      },
      "extract": {
        "html": {
          "total_text": {
            "selector": "nav ol li:last-child"
          }
        },
        "html_items": {
          "cars": {
            "fields": {
              "details": {
                "selector": "[data-testid=\"listing-details-attributes\"]"
              },
              "href": {
                "attr": "href",
                "selector": "a[href*=\"details.html\"]"
              },
              "negotiable": {
                "selector": "[data-testid=\"price-negotiable\"]"
              },
              "price_section": {
                "selector": "[data-testid$=\"-price-section\"]"
              },
              "price_text": {
                "selector": "[data-testid=\"price-label\"]"
              },
              "seller_location": {
                "selector": "[data-testid=\"seller-info\"] span:nth-child(2)"
              },
              "seller_name": {
                "selector": "[data-testid=\"seller-info\"] span:first-child"
              },
              "sponsored": {
                "selector": "[data-testid=\"sponsored-badge\"]"
              },
              "title": {
                "selector": "[data-testid=\"listing-title-card-view\"]"
              }
            },
            "max": 40,
            "selector": "article:has([data-testid=\"listing-title-card-view\"])"
          }
        }
      },
      "foreach": {
        "as": "q",
        "in": "let $mk = lower(params.make), $t = [['mercedes-benz', '17200'], ['bmw', '3500'], ['audi', '1900'], ['volkswagen', '25200'], ['porsche', '20100'], ['ford', '9000'], ['skoda', '22900'], ['opel', '19000'], ['toyota', '24100'], ['volvo', '25100'], ['alfa romeo', '900'], ['byd', '31953'], ['citroën', '5900'], ['cupra', '3'], ['dacia', '6600'], ['ds automobiles', '235'], ['fiat', '8800'], ['honda', '11000'], ['hyundai', '11600'], ['jaguar', '12400'], ['jeep', '12600'], ['kia', '13200'], ['land rover', '14800'], ['lexus', '15200'], ['mazda', '16800'], ['mg', '17300'], ['mini', '17500'], ['mitsubishi', '17700'], ['nissan', '18700'], ['peugeot', '19300'], ['polestar', '4'], ['renault', '20700'], ['seat', '22500'], ['smart', '23000'], ['subaru', '23500'], ['suzuki', '23600'], ['tesla', '135'], ['vw', '25200'], ['mercedes', '17200'], ['citroen', '5900']], $pf = params.price_from, $pt = params.price_to, $yf = params.year_from, $km = params.max_km, $s = params.sort in [{ms: join('', [($t[?[0] == $mk] | [0][1]) || '', ';;;']), p: ($pf || $pt) && join(':', [$pf && to_string($pf) || '', $pt && to_string($pt) || '']) || `null`, fr: $yf && join('', [to_string($yf), ':']) || `null`, ml: $km && join('', [':', to_string($km)]) || `null`, sb: $s == 'relevance' && 'rel' || 'p', od: $s == 'price_desc' && 'down' || 'up'}]",
        "max": 1
      },
      "id": "search",
      "parse": "html",
      "request": {
        "headers": {
          "Accept": "text/html"
        },
        "method": "GET",
        "query": {
          "fr": "{{q.fr}}",
          "isSearchRequest": "true",
          "ml": "{{q.ml}}",
          "ms": "{{q.ms}}",
          "od": "{{q.od}}",
          "p": "{{q.p}}",
          "s": "Car",
          "sb": "{{q.sb}}",
          "vc": "Car"
        },
        "url": "/fahrzeuge/search.html"
      }
    }
  ],
  "task": "Search used cars on mobile.de by make, price, year and mileage",
  "tos": {
    "notes": "mobile.de's terms prohibit automated data extraction. One user-initiated search page at a time from the user's own browser (1 request). Contacting sellers stays on mobile.de.",
    "reviewed": false
  },
  "verify": {
    "checks": [
      "length(output.cars) > `10`",
      "length(output.cars[?price_eur > `15000` || price_eur < `5000`]) == `0`",
      "length(output.cars[?first_registration != `null` && to_number(split(first_registration, '-')[0]) < `2018`]) == `0`",
      "length(output.cars[?mileage_km > `100000`]) == `0`",
      "length(output.cars[?sponsored]) == `0`",
      "starts_with(output.cars[0].url, 'https://suchen.mobile.de/fahrzeuge/details.html?id=')"
    ],
    "example_params": {
      "make": "Volkswagen",
      "max_km": 100000,
      "price_from": 5000,
      "price_to": 15000,
      "sort": "price_asc",
      "year_from": 2018
    },
    "max_ms": 6000
  },
  "version": 2
}