# Bien'ici Search

One upstream lookup per request. Resolve free text to zone ids with the locations endpoint first and pass them as zone_ids — search deliberately does not resolve place names for you, because that would cost a second upstream lookup inside one billable request. zone_ids is the only location identifier that filters: there is no location_id parameter, and an INSEE or postal code passed in its place is accepted and silently ignored, which returns unfiltered national stock instead of an error. Each ad is normalized so price reads as min/max/currency/disclosed with unit "total" — a euro amount for the whole property — and ads whose transactionType does not match the request are removed, because the upstream filter expression does not reliably hold. property_type cannot be combined with transaction_type=new_build: new build is expressed as a programme filter, so the pair would be accepted and then ignored. The upstream total is not published: it is a global counter rather than a result count (976 427 on a two-ad Paris page), so returnedCount is the number of ads in the response and from/perPage are the paging echo.

- **Documentation:** [https://scrappa.co/docs/bienici-api/bienici_search](https://scrappa.co/docs/bienici-api/bienici_search)
- **API group:** Bien'ici API
- **Endpoint:** `GET https://scrappa.co/api/bienici/search`

## Authentication

Send your Scrappa API key in the `X-API-KEY` request header. Paid endpoints also support accountless x402 payments when called without an API key.

## Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `transaction_type` | string | No | buy (achat), rent (location), or new_build (neuf, which searches new-build programmes). |
| `zone_ids` | string[] | No | Repeatable zone ids from the locations endpoint. -7444 is Paris: the captured search in tests/Fixtures/BienIci/search.json is exactly that zone id and returns Paris ads. Zone ids are hyphenated strings upstream; plain numbers are accepted and normalized, but the locations endpoint returns them as strings. |
| `postal_code` | string[] | No | Repeatable 5-digit postal codes applied after the search, for exact postal-code matching. |
| `min_price` | number | No | Minimum price. |
| `max_price` | number | No | Maximum price. |
| `min_area` | number | No | Minimum floor area in m². |
| `max_area` | number | No | Maximum floor area in m². |
| `min_bedrooms` | integer | No | Minimum bedrooms (chambres), excluding the living room. |
| `max_bedrooms` | integer | No | Maximum bedrooms (chambres). |
| `min_rooms` | integer | No | Minimum total rooms (pièces). |
| `max_rooms` | integer | No | Maximum total rooms (pièces). |
| `min_garden_area` | number | No | Minimum land area in m². |
| `max_garden_area` | number | No | Maximum land area in m². |
| `energy_classification` | string | No | Energy performance letter, for example D. |
| `on_the_market` | boolean | No | Only ads currently on the market. |
| `new_only` | boolean | No | Only new properties. |
| `sort` | string | No | Sort order key. Only publicationDate is offered; the upstream default relevance sort mixes buy ads into rent results. |
| `sort_order` | string | No | asc or desc, default desc. |
| `page` | integer | No | 1-based page. page and size must not address a window beyond 2500 results. |
| `size` | integer | No | Ads per page, 1 to 500. |

## Example request

```bash
#!/bin/bash

curl -X GET \
    -H "x-api-key: YOUR_API_KEY_HERE" \
    "https://scrappa.co/api/bienici/search?transaction_type=rent&zone_ids%5B0%5D=-7444&size=2"
```

## Example response

```json
{
    "success": true,
    "data": {
        "realEstateAds": [
            {
                "id": "ag750725-49688129",
                "reference": "602996",
                "transactionType": "rent",
                "propertyType": "flat",
                "price": {
                    "min": null,
                    "max": null,
                    "currency": null,
                    "disclosed": false,
                    "unit": "total"
                },
                "surfaceArea": 40,
                "roomsQuantity": 2,
                "city": "Paris",
                "postalCode": "75007"
            },
            {
                "id": "snpi-1101655",
                "reference": "918",
                "transactionType": "rent",
                "propertyType": "flat",
                "price": {
                    "min": null,
                    "max": null,
                    "currency": null,
                    "disclosed": false,
                    "unit": "total"
                },
                "surfaceArea": 92,
                "roomsQuantity": 3,
                "bedroomsQuantity": 2,
                "city": "Paris",
                "postalCode": "75015"
            }
        ],
        "returnedCount": 2,
        "from": 0,
        "perPage": 2
    },
    "meta": {
        "endpoint_family": "search"
    }
}
```

## Errors

| Status | Error | Description |
| --- | --- | --- |
| 404 | Not Found | The requested house was not found. This response is not billable. |
| 422 | Validation Error | A public parameter is invalid. This response is not billable. |
| 503 | Service Unavailable | The service could not obtain a complete result. This response is not billable. |

## More Scrappa resources

- [API documentation](https://scrappa.co/docs)
- [Full LLM-readable API reference](https://scrappa.co/llms-full.txt)
- [OpenAPI specification](https://scrappa.co/docs/api.json)
- [Pricing](https://scrappa.co/pricing)
