> ## Documentation Index
> Fetch the complete documentation index at: https://doc.fluximmo.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Estimer un bien immobilier via l'API Fluximmo

> Estimez le prix d'un bien immobilier français via l'API : localisation et caractéristiques en entrée, prix et fourchette (priceRange) en sortie.

## Goal

Obtenir une **estimation de prix** (vente ou location) pour un bien à partir de ses caractéristiques (localisation, surface, nombre de pièces, type), avec un intervalle indicatif — sans entraîner son propre modèle.

## Scénario

Un produit AVM (fintech, proptech, courtier, agence) doit afficher une estimation au moment où l'utilisateur saisit son bien. Le besoin : un prix central + un intervalle, et la possibilité de scorer un portefeuille en arrière-plan.

<Note>
  **Endpoint synchrone et latent.** Compter **quelques secondes** par requête — pas un appel adapté à un thread UI bloquant. Prévoir un état de chargement explicite côté UI, et un job en arrière-plan pour les batches portfolio.
</Note>

## Étapes

<Steps>
  <Step title="1. Construire le payload">
    Le minimum requis : **localisation géocodée** (`location.locationCoordinate.location` au format `[lng, lat]`), **caractéristiques du bien** (`habitation.surface.total`, `habitation.roomCount`, `habitation.bedroomCount` — tous trois requis ; optionnel `land.surface` pour les maisons), **type** (`CLASS_FLAT` | `CLASS_HOUSE`) et **offer** (objet `{ type: "OFFER_BUY" }` — seul `OFFER_BUY` est supporté sur le lite).

    ```json theme={null}
    {
      "location": {
        "locationCoordinate": {
          "location": [2.3376, 48.8606]
        }
      },
      "habitation": {
        "surface": { "total": 60 },
        "roomCount": 3,
        "bedroomCount": 2
      },
      "type": "CLASS_FLAT",
      "offer": { "type": "OFFER_BUY" }
    }
    ```

    <Note>
      **Champs optionnels qui affinent l'estimation** (tous documentés au swagger) :

      * `land.surface` — pour les maisons
      * `habitation.propertyCondition` : `constructionYear`, `generalConditions[]`
      * `habitation.climate` : `epcEnergy` (DPE), `epcClimate` (GES)
      * `habitation.characteristics` : `hasBalcony`, `hasCellar`, `hasGarage`, `hasLift`, `hasParking`, `hasPool`, `hasTerrace`
      * `habitation.features` : `furniture`, `propertyFloor`, `propertyTotalFloor`

      Plus le payload est riche, plus l'estimation est calibrée — surtout sur des biens atypiques (DPE F/G, dernier étage sans ascenseur, etc.). Voir [`POST /estimate/property/lite`](/api-ai-reference/estimations/lite-property-estimation) pour le schéma OpenAPI complet.
    </Note>
  </Step>

  <Step title="2. Appeler l'endpoint">
    ```bash theme={null}
    curl -X POST https://api.fluximmo.io/v2/protected/estimate/property/lite \
      -H "x-api-key: $FLUXIMMO_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "location": { "locationCoordinate": { "location": [2.3376, 48.8606] } },
        "habitation": { "surface": { "total": 60 }, "roomCount": 3, "bedroomCount": 2 },
        "type": "CLASS_FLAT",
        "offer": { "type": "OFFER_BUY" }
      }'
    ```
  </Step>

  <Step title="3. Parser la réponse">
    La réponse, sous la clé `data`, contient (cf. `EstimationResponseDto` du swagger) :

    * `data.price` — estimation centrale (€) — **requis**
    * `data.priceRange` — intervalle `{ lower, upper }` — **requis**
    * `data.metadata` — objet libre, optionnel, sans schéma défini par l'API

    ```text theme={null}
    # Pseudocode
    parse(payload):
        central     = payload.data.price
        range_lower = payload.data.priceRange.lower
        range_upper = payload.data.priceRange.upper
        spread_pct  = (range_upper - range_lower) / central * 100   if central > 0
        return { central, range_lower, range_upper, spread_pct, metadata = payload.data.metadata }
    ```

    <Note>
      **Pas de champ de fiabilité officiel.** Le swagger ne définit ni `confidence`, ni `spread`, ni `sample_size`. `spread_pct` est une **heuristique calculée côté client** : plus l'intervalle `[lower, upper]` est large par rapport à `central`, plus l'incertitude est forte sur cette zone / ce type de bien. **Afficher l'intervalle complet à l'utilisateur** plutôt que le seul prix central — c'est l'information honnête que l'API vous donne.
    </Note>
  </Step>

  <Step title="4. Cas d'usage AVM par batch">
    Pour scorer un portefeuille (N biens), lancer un **job en arrière-plan**, jamais une boucle dans une requête HTTP entrante. L'endpoint étant synchrone et latent, paralléliser agressivement saturerait le service — et ne ferait pas gagner de temps utilisateur, puisque le batch tourne déjà hors UI.

    * **Séquentiel par défaut.** Le débit utile est dicté par la latence backend, pas par votre concurrence client. Si vous tenez à paralléliser, restez **bas** (1-2 workers) et validez avec `contact@fluximmo.com` avant de pousser plus haut.
    * **Cache.** C'est le vrai levier de débit. Clé = hash des champs métier (coordonnées arrondies + `surface.total` + `roomCount` + `bedroomCount` + `type` + `offer.type`, plus les optionnels que vous utilisez réellement). Les estimations sont stables sur quelques heures.
    * **Quota.** Chaque appel est crédité. Avant un batch, vérifier le solde via [`GET /v2/protected/consumption`](/api-v2-reference/consumption/get-your-credit-consumption).

    ```text theme={null}
    # Pseudocode batch (worker en arrière-plan)
    foreach bien in portfolio:
        lng, lat = bien.location.locationCoordinate.location
        key = hash(round(lng,3), round(lat,3),
                   bien.habitation.surface.total,
                   bien.habitation.roomCount,
                   bien.habitation.bedroomCount,
                   bien.type, bien.offer.type)
        if cache[key] not stale:
            result = cache[key]
        else:
            result = POST /v2/protected/estimate/property/lite (bien)   # appel séquentiel
            cache[key] = result
        persist(bien.id, result)
    ```
  </Step>
</Steps>

## Architecture / flow

```mermaid theme={null}
flowchart LR
    User[App / Worker]
    Lite["POST /estimate/property/lite"]
    AI[Modèle AVM Fluximmo]
    Output[Résultat utilisateur<br/>price + priceRange]

    User -->|"location + habitation + type + offer"| Lite
    Lite --> AI
    AI -->|"price, priceRange, metadata"| User
    User --> Output
```

## Pièges fréquents

<Warning>
  **Endpoint synchrone latent.** Compter quelques secondes par appel. Ne **jamais** appeler depuis un thread UI bloquant ni boucler en synchrone dans une requête HTTP entrante : prévoir un job en arrière-plan + état de chargement explicite côté UI.
</Warning>

<Warning>
  **Géocodage incomplet.** Sans coordonnées `lat`/`lon` correctement résolues dans `location.locationCoordinate.location`, l'estimation tombe sur des moyennes nationales — résultat peu fiable. Toujours géocoder l'adresse en amont via [`/geocoding/search`](/api-geocoding-reference/search/recherche-par-géocodage-direct).
</Warning>

<Warning>
  **Zones non couvertes.** DOM-TOM, étranger, communes \< 500 habitants : la base d'apprentissage est plus mince. L'API n'expose **pas** de signal officiel de fiabilité dans la réponse — surveiller la largeur de `priceRange` (`upper - lower`) par rapport à `price`, et afficher un disclaimer côté UI si l'intervalle est large.
</Warning>

<Warning>
  **Surcoût quota.** Chaque appel est crédité. Pour un batch portfolio, vérifier `GET /v2/protected/consumption` avant et mettre en cache (clé = hash des champs métier). Sinon vous brûlez votre solde sur des requêtes redondantes.
</Warning>

## Pour aller plus loin

* [Estimation lite — référence API](/api-ai-reference/estimations/lite-property-estimation)
* [Géocoder pour search](/playbooks/geocoder-pour-search) — pipeline géocodage en amont
* [Consumption](/api-v2-reference/consumption/get-your-credit-consumption) — surveiller le quota

<Card title="Clé test gratuite — 1 semaine" icon="key" href="https://my.fluximmo.io">
  Créez un compte sur **my.fluximmo.io** pour récupérer une clé API test gratuite (1 semaine, accès limité). Aucun paiement requis.
</Card>
