> ## 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.

# Recevoir une alerte ADVERT par département

> Webhook temps réel sur les nouvelles annonces d'achat appartement dans un département (chasseur immo).

## Goal

Recevoir, en quasi temps réel, **chaque nouvelle annonce de vente d'appartement** publiée sur n'importe quel portail dans un département donné — pour vous permettre d'être le premier à contacter le vendeur.

## Scénario

Vous êtes chasseur immobilier (ou app B2C de chasse). Vous voulez surveiller toutes les nouvelles publications d'appartements à l'achat dans le département **75** (Paris). Volume attendu : \~200-500 nouvelles annonces / jour selon la période. Vous devez aussi détecter, plus tard, les **baisses de prix** et les **mises hors ligne** sur ces mêmes annonces.

<Note>
  **Quand utiliser ADVERTS plutôt que PROPERTIES ?** Les alertes ADVERT sont nécessaires si vous voulez :

  * **post-traiter les annonces** / construire un pipeline de traitement interne (enrichissement, scoring, dédup custom)
  * **exposer vos propres APIs** à vos utilisateurs finaux
  * **répliquer la BDD Fluximmo** side-by-side
  * **recevoir 100 % des events de dépublication** (créations, mises à jour de prix, mises hors ligne)

  Pour un cas d'usage purement "trouver les biens", préférez PROPERTY (cf. [property-vs-advert](/concepts/property-vs-advert)).
</Note>

<Snippet file="/snippets/banniere-llm-context.mdx" />

## Étapes

<Steps>
  <Step title="1. Configurer un endpoint webhook qui ack en moins de 1 s">
    Le handler HTTP doit valider le header `x-webhook-key`, **enqueuer** le payload dans une file durable (SQS, RabbitMQ, Redis Streams), puis répondre **200**. Aucun traitement métier synchrone — sinon Fluximmo timeout et retry, vous saturerez votre app.

    ```text theme={null}
    # Pseudocode handler
    on POST /webhooks/fluximmo:
        if header.x-webhook-key != EXPECTED_KEY: return 401
        enqueue(request.body)
        return 200
    ```

    Smoke test depuis votre poste :

    ```bash theme={null}
    curl -i -X POST https://votre-domaine.com/webhooks/fluximmo \
      -H "Content-Type: application/json" \
      -H "x-webhook-key: $FLUXIMMO_WEBHOOK_KEY" \
      -d '{"ping": true}'
    ```

    Détails — politique de retry, SLO réponse, sécurité — sur [/concepts/webhooks](/concepts/webhooks).
  </Step>

  <Step title="2. Créer l'alerte ADVERT (achat appartement, dpt 75)">
    Filtre `isOnline: true` recommandé en production : vous ne recevez que des adverts actuellement publiées sur leur portail.

    ```bash theme={null}
    curl -X PUT "https://api.fluximmo.io/v2/protected/adverts/search/alerts" \
      -H "x-api-key: $FLUXIMMO_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "search_query": {
          "filterAd": {
            "location": { "department": "75" },
            "type": ["CLASS_FLAT"],
            "offer": [{ "type": "OFFER_BUY" }],
            "isOnline": true
          }
        },
        "webhook_url": "https://votre-domaine.com/webhooks/fluximmo",
        "match": ["ALERT_MATCH_CREATED"],
        "search_name": "Achat appart Paris (75)"
      }'
    ```

    Conservez l'`flxId` retourné : c'est la clé pour **modifier** l'alerte plus tard (étape 4) sans perdre l'historique.
  </Step>

  <Step title="3. Recevoir le premier webhook (ALERT_MATCH_CREATED)">
    Dès qu'une nouvelle advert qualifiante est ingérée (\~1 min après publication portail), Fluximmo POSTe le payload **complet de l'advert** sur `webhook_url`. Pas de refetch nécessaire, contrairement aux alertes Properties.

    Structure type (shape canonique — cf. [exemple webhook adverts](/api-v2-reference/sample-adverts/sample-advert-webhook-body)) :

    ```json theme={null}
    {
      "data": {
        "created": [
          {
            "alert_id": "alrt_...",
            "adverts": [
              {
                "flxId": "adv_...",
                "propertyFlxId": "adv_...",
                "source": "<portail>",
                "currentPrice": { "value": 285000 },
                "habitation": { "surface": { "total": 42 }, "roomCount": 2 },
                "location": { "postalCode": "75011" },
                "isOnline": true
              }
            ]
          }
        ],
        "updated": []
      }
    }
    ```

    Boucle d'extraction : `for entry in body.data.created: for advert in entry.adverts: ...`. Mappez `advert.flxId` sur votre BDD comme **clé d'idempotence** — vous recevrez parfois le même match deux fois (retry).
  </Step>

  <Step title="4. Étendre l'alerte aux events PRICE / REPUBLISHED / UNPUBLISHED — en PATCH">
    Une fois la première vague de matches digérée, étendez le tableau `match` avec `ALERT_MATCH_ADVERT_EVENT`.

    <Snippet file="/snippets/warning-cycle-vie-alerte.mdx" />

    **À faire** : `PATCH /v2/protected/adverts/search/alerts/{alertId}` (modify in place).
    **À NE PAS faire** : `DELETE` puis `PUT` d'une nouvelle alerte — vous **perdez** l'historique des adverts déjà matchées, donc plus aucun event sur ces annonces.

    ```bash theme={null}
    curl -X PATCH \
      "https://api.fluximmo.io/v2/protected/adverts/search/alerts/$ALERT_FLX_ID" \
      -H "x-api-key: $FLUXIMMO_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "match": ["ALERT_MATCH_CREATED", "ALERT_MATCH_ADVERT_EVENT"] }'
    ```

    Les events arrivent désormais dans la branche `data.updated[]` du même webhook. Le payload `updated` ne porte que `flxId`, `currentPrice`, `isOnline` (DTO réduit) — vous **dérivez** côté client le type d'event en comparant avec votre état stocké : `currentPrice.value` change → PRICE, `isOnline` flip → REPUBLISHED ou UNPUBLISHED. Cf. [Match types & cycle alerte](/concepts/match-types-cycle-alerte).
  </Step>

  <Step title="5. Backfill historique : demander la réception du passé sur le webhook">
    Une alerte ne match **que** ce qui est ingéré **après** sa création (`createdAt`). Pour récupérer les annonces déjà au catalogue, écrivez à [contact@fluximmo.com](mailto:contact@fluximmo.com) en précisant :

    * Votre `clientId`
    * Le `flxId` de l'alerte créée à l'étape 2
    * La période de backfill souhaitée (ex. derniers 30 jours, derniers 6 mois)
    * Le volume estimé que votre webhook peut absorber

    Le backfill est rejoué sur votre webhook avec le même format de payload que les matches normaux — votre handler le traite sans changement de code, idempotence via `advert.flxId`.
  </Step>
</Steps>

## Architecture / flow

```mermaid theme={null}
flowchart LR
  U["Vous<br/>(PUT alerte)"] --> FX["Fluximmo<br/>(crawler + matcher)"]
  FX -- "advert qualifiée" --> WH["POST webhook<br/>x-webhook-key"]
  WH --> H["Handler HTTP<br/>(stateless, < 1 s)"]
  H -->|"valide key"| Q["Queue durable<br/>(SQS / RabbitMQ)"]
  H -->|"200 OK"| FX
  Q --> WK["Worker async<br/>(scalable)"]
  WK --> DB["Votre BDD<br/>(idempotent sur flxId)"]
  WK --> NOTIF["Notif user<br/>email / push"]
```

## Pièges fréquents

<Warning>
  * **Traitement synchrone dans le handler** → timeout, retry, cascade d'échecs sous charge. Ackez en \< 1 s, traitez en worker async.
  * **Idempotence oubliée** : un même webhook peut être livré 2 fois (retry après timeout réseau). Dédupliquez avec une clé stable comme `(advert.flxId, branch, alert_id)` où `branch` ∈ `{ "created", "updated" }`.
  * **`DELETE` + recréation** au lieu de `PATCH` → perte de l'historique des adverts matchées, donc **plus aucun event** sur ces annonces.
  * **Pas de backfill côté serveur sans demande** : l'alerte ne voit que le futur. Pour le passé, demande explicite par mail (cf. étape 5).
  * **Volume sous-estimé** : achat appartement dpt 75 ≈ 200-500 nouvelles annonces/jour. Provisionnez la queue et le worker en conséquence (peak intra-day en matinée).
</Warning>

## Pour aller plus loin

* [Match types & cycle de vie d'une alerte](/concepts/match-types-cycle-alerte)
* [Webhooks — architecture, retry, sécurité](/concepts/webhooks)
* [Créer une alerte adverts (référence API)](/api-v2-reference/adverts-alerts/create-a-new-advert-alert-for-this-search)
* [Playbook — Architecture webhook haute volumétrie](/playbooks/webhook-volume-architecture)
* [Playbook — Suivi des changements de prix](/playbooks/track-price-changes)

<Snippet file="/snippets/cta-cle-test-gratuite.mdx" />
