# willhaben API scraper — Austria's largest classifieds site: marketplace search with condition, PayLivery and private/dealer filters, real estate (rent and buy) and cars/motorcycles search, and the full listing record. No account, no browser; private sellers' personal data withheld.

> Search willhaben's second-hand marketplace (Kaufen & Verkaufen) by keyword and/or category: price or 'free', condition, PayLivery (willhaben's buyer-protected shipping) and pickup/shipping, location, private or dealer seller, publish/update/expiry dates, images, and flags for top ads, paid highlights and reserved listings. Filter by price, condition, handover, PayLivery, state or district, seller type, seller, attribute values and last 48 hours; sort newest, price or relevance.
> ReefAPI engine `willhaben` · 4 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/willhaben/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed calls are free except verified SHEIN NOT_FOUND on product/detail and price (4 credits).
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /willhaben/v1/search — 1 credit
Search willhaben's second-hand marketplace (Kaufen & Verkaufen) by keyword and/or category: price or 'free', condition, PayLivery (willhaben's buyer-protected shipping) and pickup/shipping, location, private or dealer seller, publish/update/expiry dates, images, and flags for top ads, paid highlights and reserved listings. Filter by price, condition, handover, PayLivery, state or district, seller type, seller, attribute values and last 48 hours; sort newest, price or relevance.

**Parameters:**
- `query` (string, optional) — Free-text keyword, as typed into willhaben's search box.
- `category` (string, optional) — willhaben category id (e.g. 4525 = bikes) or a willhaben category URL ending in -<id>. Ids come back in facets.
- `condition` (array, optional) — One or more of new, like_new, refurbished, used, defective, display_item. [one of: new, like_new, refurbished, used, defective, display_item]
- `handover` (enum, optional) — Only listings offering pickup, or shipping. [one of: pickup, shipping]
- `paylivery` (boolean, optional) — Only listings with PayLivery (buyer protection + shipping via willhaben).
- `attribute_ids` (array, optional) — willhaben attribute value ids (frame size, colour, size…) from facets.
- `price_min` (number, optional) — Lowest price in EUR (monthly rent on rental sections).
- `price_max` (number, optional) — Highest price in EUR (monthly rent on rental sections).
- `state` (enum, optional) — Austrian federal state. [one of: burgenland, kaernten, niederoesterreich, oberoesterreich, salzburg, steiermark, tirol, vorarlberg, wien]
- `area_id` (integer, optional) — willhaben area id for a district or city (e.g. 117223 = Wien 1st district). Returned in facets when include_facets=true. Use instead of state.
- `seller_type` (enum, optional) — Private sellers or dealers only. [one of: private, dealer]
- `seller_id` (integer, optional) — Only this seller's listings (a listing's seller_id).
- `posted_last_48h` (boolean, optional) — Only listings published in the last 48 hours.
- `sort` (enum, optional) — newest, price_asc, price_desc or relevance. Omitted: willhaben's default order (sort_applied says which). [one of: newest, price_asc, price_desc, relevance]
- `page` (integer, optional, default 1) — Result page, 1-based.
- `limit` (integer, optional, default 30) — Listings per page (1-100). willhaben's own page size is 30.
- `include_facets` (boolean, optional, default false) — Also return willhaben's filter facets for this search (categories, areas, makes, object types, attribute values) with counts and the value to pass back.
- `include_pii` (boolean, optional, default false) — Return private sellers' names, contact names, phone numbers, street addresses and exact coordinates. Off by default.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** listings[]{ad_id, title, url, section, status, is_reserved, price (EUR; 0 only when free; null on request), currency, price_display, is_free, price_on_request, price_is_from, price_not_published, description_preview, postcode, location, district, state, country, address (dealers only), latitude, longitude (dealers only), published_at, updated_at, expires_at, seller_id, seller_type (private|dealer), seller_name (dealers only), images[], image_count, is_top_ad, is_highlighted, is_bumped, category_ids[], teaser[], condition, handover[], paylivery}, count, total, page, limit, has_more, sort_applied, breadcrumbs[], facets[] (include_facets)

**Example request body:**
```json
{
  "query": "fahrrad"
}
```

### POST /willhaben/v1/real_estate/search — 1 credit
Search willhaben real estate - Austria's largest property portal - by property type (apartments and houses to rent or buy, plots, commercial): price or monthly rent, price per m², living area, rooms, floor, property type, new-build projects with their units, address and district, agency or private landlord, images and top-ad flags. Filter by price, living area, rooms, state or district, agency, available now, keyword; sort newest, price, area or relevance.

**Parameters:**
- `property_type` (enum, required) — rent_apartment, buy_apartment, rent_house, buy_house, plot, commercial_rent or commercial_buy. [one of: rent_apartment, buy_apartment, rent_house, buy_house, plot, commercial_rent, commercial_buy]
- `query` (string, optional) — Free-text keyword, as typed into willhaben's search box.
- `price_min` (number, optional) — Lowest price in EUR (monthly rent on rental sections).
- `price_max` (number, optional) — Highest price in EUR (monthly rent on rental sections).
- `living_area_min` (number, optional) — Smallest living area, m².
- `living_area_max` (number, optional) — Largest living area, m².
- `rooms` (array, optional) — One or more of 1, 2, 3, 4, 5, 6-9, 10+. [one of: 1, 2, 3, 4, 5, 6-9, 10+]
- `available_now` (boolean, optional) — Only properties available immediately.
- `state` (enum, optional) — Austrian federal state. [one of: burgenland, kaernten, niederoesterreich, oberoesterreich, salzburg, steiermark, tirol, vorarlberg, wien]
- `area_id` (integer, optional) — willhaben area id for a district or city (e.g. 117223 = Wien 1st district). Returned in facets when include_facets=true. Use instead of state.
- `seller_id` (integer, optional) — Only this seller's listings (a listing's seller_id).
- `posted_last_48h` (boolean, optional) — Only listings published in the last 48 hours.
- `sort` (enum, optional) — newest, price_asc, price_desc, area_asc, area_desc or relevance. [one of: newest, price_asc, price_desc, area_asc, area_desc, relevance]
- `page` (integer, optional, default 1) — Result page, 1-based.
- `limit` (integer, optional, default 30) — Listings per page (1-100). willhaben's own page size is 30.
- `include_facets` (boolean, optional, default false) — Also return willhaben's filter facets for this search (categories, areas, makes, object types, attribute values) with counts and the value to pass back.
- `include_pii` (boolean, optional, default false) — Return private sellers' names, contact names, phone numbers, street addresses and exact coordinates. Off by default.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** listings[]{ad_id, title, url, section, status, is_reserved, price (EUR; 0 only when free; null on request), currency, price_display, is_free, price_on_request, price_is_from, price_not_published, description_preview, postcode, location, district, state, country, address (dealers only), latitude, longitude (dealers only), published_at, updated_at, expires_at, seller_id, seller_type (private|dealer), seller_name (dealers only), images[], image_count, is_top_ad, is_highlighted, is_bumped, category_ids[], teaser[], property{property_type, living_area_m2, usable_area_m2, rooms, floor, rent_per_month, purchase_price, price_per_m2, free_area_type, is_project, project_id, virtual_tour_url, …}, units[]{ad_id, title, url, price, price_display, living_area_m2, rooms, floor}}, count, total, page, limit, has_more, sort_applied, breadcrumbs[], facets[]

**Example request body:**
```json
{
  "property_type": "rent_apartment",
  "state": "wien"
}
```

### POST /willhaben/v1/cars/search — 1 credit
Search willhaben used cars and motorcycles: price, the dealer's earlier price and any bonus-only price kept separate, make, model, version, first registration, mileage, power, fuel, transmission, condition, body type, previous owners, warranty and inspection sticker, location, dealer or private seller, images and top-ad flags. Filter by make, price, mileage, year, fuel, transmission, condition, state, seller type; sort by price, mileage, year, newest or relevance.

**Parameters:**
- `vehicle_type` (enum, optional, default "car") — car or motorcycle. The make/fuel/transmission/condition filters apply to cars. [one of: car, motorcycle]
- `query` (string, optional) — Free-text keyword, as typed into willhaben's search box.
- `make` (integer, optional) — willhaben make id (e.g. 1003 = Audi, 1005 = BMW). Ids come back in facets.
- `price_min` (number, optional) — Lowest price in EUR (monthly rent on rental sections).
- `price_max` (number, optional) — Highest price in EUR (monthly rent on rental sections).
- `mileage_min` (number, optional) — Lowest mileage, km.
- `mileage_max` (number, optional) — Highest mileage, km.
- `year_min` (integer, optional) — Earliest first registration year.
- `year_max` (integer, optional) — Latest first registration year.
- `fuel` (enum, optional) — petrol, diesel, electric, gas, hybrid_petrol, hybrid_diesel or hydrogen. [one of: petrol, diesel, electric, gas, hybrid_petrol, hybrid_diesel, hydrogen]
- `transmission` (enum, optional) — automatic or manual. [one of: automatic, manual]
- `condition` (enum, optional) — used, new, year_old, oldtimer, day_registration, accident or demo. [one of: used, new, year_old, oldtimer, day_registration, accident, demo]
- `state` (enum, optional) — Austrian federal state. [one of: burgenland, kaernten, niederoesterreich, oberoesterreich, salzburg, steiermark, tirol, vorarlberg, wien]
- `area_id` (integer, optional) — willhaben area id for a district or city (e.g. 117223 = Wien 1st district). Returned in facets when include_facets=true. Use instead of state.
- `seller_type` (enum, optional) — Private sellers or dealers only. [one of: private, dealer]
- `seller_id` (integer, optional) — Only this seller's listings (a listing's seller_id).
- `posted_last_48h` (boolean, optional) — Only listings published in the last 48 hours.
- `sort` (enum, optional) — newest, price_asc, price_desc, mileage_asc, mileage_desc, year_desc, year_asc or relevance. [one of: newest, price_asc, price_desc, mileage_asc, mileage_desc, relevance, year_desc, year_asc]
- `page` (integer, optional, default 1) — Result page, 1-based.
- `limit` (integer, optional, default 30) — Listings per page (1-100). willhaben's own page size is 30.
- `include_facets` (boolean, optional, default false) — Also return willhaben's filter facets for this search (categories, areas, makes, object types, attribute values) with counts and the value to pass back.
- `include_pii` (boolean, optional, default false) — Return private sellers' names, contact names, phone numbers, street addresses and exact coordinates. Off by default.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** listings[]{ad_id, title, url, section, status, is_reserved, price (EUR; 0 only when free; null on request), currency, price_display, is_free, price_on_request, price_is_from, price_not_published, description_preview, postcode, location, district, state, country, address (dealers only), latitude, longitude (dealers only), published_at, updated_at, expires_at, seller_id, seller_type (private|dealer), seller_name (dealers only), images[], image_count, is_top_ad, is_highlighted, is_bumped, category_ids[], teaser[], vehicle{make, model, model_specification, year, mileage_km, power_kw, fuel, transmission, condition, body_type, previous_owners, warranty, price_before_reduction, price_reduced_at, price_with_bonus, …}}, count, total, page, limit, has_more, sort_applied, breadcrumbs[], facets[]

**Example request body:**
```json
{
  "query": "golf"
}
```

### POST /willhaben/v1/listing — 1 credit
The full willhaben listing by ad id or URL, in any section: title, price (free, on request and from-prices labelled), description, all images and floor plans, status and reserved flag, condition, pickup/shipping, PayLivery with each shipping option's carrier, price and parcel size, location (postcode, city, district, state), publish/update/expiry dates, breadcrumb, every published attribute, property or vehicle details, top-ad flag, and the seller (dealer company, address and website; private sellers' personal data withheld).

**Parameters:**
- `ad_id` (string, required) — The willhaben ad id (the digits at the end of a listing URL), or the full listing URL.
- `include_pii` (boolean, optional, default false) — Return private sellers' names, contact names, phone numbers, street addresses and exact coordinates. Off by default.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** listing{ad_id, uuid, title, url, section, status, is_reserved, price, currency, price_display, is_free, price_on_request, price_is_from, price_not_published, description, text_sections{}, condition, condition_label, handover[], paylivery, delivery_options[]{carrier, price, price_before_discount, parcel_size, parcel_type, max_weight_kg, delivery_days, insurance}, payment_options[], location{postcode, city, municipality, district, state, country, street (dealers), latitude, longitude (dealers), area_id}, published_at, first_published_at, updated_at, expires_at, images[], image_count, floor_plans[], category_id, breadcrumbs[], attribute_groups[]{name, code, values[]}, attributes{}, is_top_ad, is_bumped, advertiser_reference, property{} | vehicle{}, seller{seller_id, type, name, name_withheld, company, business_address, website, member_since, active_ad_count, profile_image, partner_years, contact_type, chat_enabled, contact_withheld}}

## More
- Try it live, no code: https://reefapi.com/playground?engine=willhaben
- Human docs page: https://reefapi.com/docs/willhaben
- Overview page: https://reefapi.com/willhaben-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
