Skip to content
Scrappa Get API key
Willhaben API 1 credit/request

Willhaben Search API Documentation

GET https://scrappa.co/api/willhaben/search

Scrappa's `GET /api/willhaben/search` endpoint is the Willhaben Search API documentation page for developers who need Austrian property listings as structured JSON instead of building their own scraper.

## Endpoint reference for Willhaben.at property search

Use this endpoint to search Austrian apartments, houses, plots, new builds, and commercial property for rent or sale. The request supports a `vertical`, `rows`, `page`, `sort`, `keyword`, `area_id`, price bounds, living area bounds, and room filters, which makes it suitable for property search interfaces, rental alerting, market monitoring, and Austrian real estate data products.

## What the Willhaben search response returns

Each response includes the total match count, the adverts on the current page, facet values with their live hit counts, the available sort orders, breadcrumbs, and paging metadata. Advert cards carry listing ids, titles, prices, room counts, living areas, addresses, and listing URLs, so you get a search-ready listing feed instead of markup that still needs parsing.

## Choosing a vertical

All twelve Austrian property verticals are available: rental apartments, owner-occupied apartments, houses for sale, houses for rent, new builds, plots, commercial property for sale, commercial property for rent, holiday property for sale, holiday property for rent, other, and the full rollup. Omit the parameter to search rental apartments.

## Paging and result limits

Request up to 200 listings per page. Asking for more than 200, or for a page above 999, is rejected with a 422 rather than silently truncated, so a short page is never mistaken for a complete one. Keep paging until a page returns no adverts; an empty page is the end of the results.

## How this differs from a Willhaben scraper build

If you are evaluating how to scrape Willhaben.at, this endpoint replaces the brittle search step with one documented API call. Scrappa handles request routing, extraction, and normalization so your application can focus on query logic and downstream analysis rather than browser automation, proxy rotation, or parser upkeep.

## When to pair this endpoint with the other Willhaben docs

Use [Willhaben Locations](/docs/willhaben-api/willhaben_locations) to resolve provinces and districts before searching. Use [Autocomplete](/docs/willhaben-api/willhaben_autocomplete) for search-as-you-type interfaces. Use [Listing Details](/docs/willhaben-api/willhaben_details) when a card needs to be expanded into a full listing record.</p>
Willhaben Search API Documentation 1 credit/request

Endpoint

Request preview
GET
https://scrappa.co/api/willhaben/search
Auth header
x-api-key
Cost
1 credit/request
Response preview
200 OK
{
    "data": {
        "results": [
            {
                "id": "2059921960",
                "price": 1290,
                "rooms": 2,
                "title": "Helle 2-Zimmer-Wohnung im 10. Bezirk",
                "livingArea": 68
            }
        ],
        "vertical": {
            "id": 131,
            "label": "Mietwohnungen"
...

Parameters

Start with the required fields, then add optional filters only when your use case needs them.

Runnable path

This endpoint has no required query parameters.

11 optional filters available.

vertical integer Optional

Vertical id. One of: 12 Ferienimmobilien kaufen, 14 Grundstuecke, 15 Gewerbe kaufen, 16 Gewerbe mieten, 32 Ferienimmobilien mieten, 35 Sonstige, 42 Neubauprojekte, 90 Immobilien, 101 Eigentumswohnung, 102 Haus kaufen, 131 Mietwohnungen, 132 Haus mieten. Defaults to 131 (Mietwohnungen). An id outside this list is rejected with a 422 rather than silently returning rentals.

Example value 10
rows integer Optional

Listings per page, up to 200. Asking for more is rejected with a 422, not clamped.

Example value 10
page integer Optional

Page number, up to 999. A page above 999 is rejected with a 422, not clamped.

Example value 1
sort string Optional

Sort order id. Valid ids come from the sortOrderList field of a search response for the same vertical; they differ per vertical.

Example value relevance
keyword string Optional

Free-text search term.

Example value running shoes
area_id integer Optional

Location id from the locations endpoint. One id per request: the upstream API accepts a repeatable areaId, but this endpoint exposes a single integer, so multi-area queries need separate calls. The upstream sfId and ISPRIVATE switches are not exposed.

Example value 1234567890
price_from number Optional

Minimum price.

Example value 10
price_to number Optional

Maximum price.

Example value 10
living_area_from number Optional

Minimum living area.

Example value 10
living_area_to number Optional

Maximum living area.

Example value 10
rooms string Optional

Room count bucket.

Example value example

Response Schema

Example response fields are illustrative; inspect the JSON before integrating.

Example response fields

Scan these fields before integrating.

data success
JSON Response
200 OK
{
    "data": {
        "results": [
            {
                "id": "2059921960",
                "price": 1290,
                "rooms": 2,
                "title": "Helle 2-Zimmer-Wohnung im 10. Bezirk",
                "livingArea": 68
            }
        ],
        "vertical": {
            "id": 131,
            "label": "Mietwohnungen"
        },
        "rowsFound": 19500,
        "rowsReturned": 50,
        "pageRequested": 1,
        "rowsRequested": 50
    },
    "success": true
}

Errors

Handle these documented responses before retrying or showing customer-facing failures.

404

Not Found

The requested listing, agency or seller does not exist upstream. Non-billable, and not retryable: a different exit returns the same 404.

{
    "meta": {
        "billable": false,
        "retryable": false
    },
    "error": {
        "code": "NOT_FOUND",
        "message": "The requested Willhaben resource was not found.",
        "failure_type": "not_found"
    },
    "success": false
}
422

Validation Error

A query parameter failed validation — a missing required id, an unknown vertical, or a value outside the documented range. Messages are per field in Laravel's standard wording, so the accepted vertical ids are published on the `vertical` parameter of each page rather than repeated in the message. Non-billable.

{
    "errors": {
        "adId": [
            "The adId field is required."
        ]
    },
    "message": "The request validation failed"
}
503

Upstream Rejected The Request

Willhaben answered with a JSON application error — an invalid filter, or a sort id that the vertical does not offer. Non-billable, and not retryable: the same request fails the same way on every exit. Published as 503 because SanitizeApiErrorResponse rewrites every upstream 502 before the response leaves the app; branch on `meta.retryable` rather than on the status code.

{
    "meta": {
        "billable": false,
        "retryable": false
    },
    "error": {
        "code": "UPSTREAM_REJECTED",
        "message": "Willhaben could not accept this request. Please check the filters and retry.",
        "failure_type": "invalid_request"
    },
    "success": false
}
503

Temporarily Unavailable

Willhaben could not be reached at all: no exit was available, the transport failed, the edge refused every exit, or every exit was rate limited. All of these rotate and retry, so this row is always retryable. The `failure_type` says which one happened — `upstream_unreachable`, `transport_error`, `edge_blocked`, `rate_limited` or `attempts_exhausted` — so a caller can tell a dead provider from a throttled one. Non-billable; a later request with a fresh pool fetch is worth making.

{
    "meta": {
        "billable": false,
        "retryable": true
    },
    "error": {
        "code": "UPSTREAM_UNAVAILABLE",
        "message": "The Willhaben API is temporarily unavailable. Please retry.",
        "failure_type": "transport_error"
    },
    "success": false
}

Generate Code with AI

Copy a ready-made prompt with all the endpoint details, parameters, and example responses. Paste it into ChatGPT, Claude, or any AI assistant to instantly generate working code.

Try It Live

Test this endpoint in our interactive playground with real data.