Skip to main content

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.

Un webhook Fluximmo est un POST HTTPS émis par notre infrastructure vers une URL que vous fournissez à la création d’une alerte. Il porte les matches d’annonces (nouveaux biens, changements de prix, mises hors ligne, fusions) en quasi temps réel — typiquement dans la minute qui suit l’ingestion d’une annonce ou l’occurrence d’un événement.

Pipeline de livraison

Côté client, le pattern recommandé est inverse : ne traitez jamais le webhook dans la requête HTTP, ackez en moins de 100 ms et empilez le payload dans une queue durable (RabbitMQ, SQS, Kafka, Redis Streams). Un worker async fait ensuite le travail métier.

Payloads : Adverts vs Properties

AspectAdvertsProperties
Contenu du payloadAdvertDto complet (créations) + DTO réduit (updates)IDs uniquement (propertyFlxId[])
Refetch nécessaire ?Non pour les créations — voir note ci-dessous pour les updatesOui : GET /v2/protected/properties/{flxId}
Volume réseauÉlevé (jusqu’à plusieurs Mo par batch)Faible (liste d’IDs)
Latence métierFaible (zéro round-trip API)+1 round-trip HTTP par property
Cas d’usage typiqueMonitoring temps réel, miroir BDDAnalytics, déduplication, valorisation
Pourquoi cette asymétrie ? Une Property est une entité agrégée qui peut évoluer entre l’émission et la réception du webhook (un nouvel advert peut s’y rattacher). Refetcher garantit la version la plus fraîche au moment où vous la traitez.

Shape canonique (côté ADVERT)

Le payload reçu est toujours wrappé sous data avec deux branches created (nouvelles adverts matchées) et updated (changements sur des adverts précédemment matchées) :
{
  "data": {
    "created": [
      {
        "alert_id": "alr_xxx",
        "adverts": [ /* AdvertDto complet : flxId, propertyFlxId, currentPrice, habitation, location, source, isOnline... */ ]
      }
    ],
    "updated": [
      {
        "alert_id": "alr_xxx",
        "adverts": [ /* DTO réduit : flxId, currentPrice (value + valuePerArea), isOnline */ ]
      }
    ]
  }
}
Events PRICE / REPUBLISHED / UNPUBLISHED ne sont pas explicitement émis. Ils se dérivent côté client en comparant les adverts de data.updated[] avec votre état local stocké : currentPrice.value qui change ⇒ PRICE, isOnline qui flip ⇒ REPUBLISHED ou UNPUBLISHED. Voir Match types & cycle alerte et le playbook track prix.

Sécurité — header x-webhook-key

Chaque webhook porte un header x-webhook-key que vous avez défini à la création de l’alerte (champ webhook.headerValue ou équivalent dans le payload alerte). Validez-le côté client avant tout traitement.
from fastapi import FastAPI, Request, Header, HTTPException
import os

EXPECTED_KEY = os.environ["FLUXIMMO_WEBHOOK_KEY"]
app = FastAPI()

@app.post("/webhook/fluximmo")
async def handler(req: Request, x_webhook_key: str = Header(default="")):
    if x_webhook_key != EXPECTED_KEY:
        raise HTTPException(status_code=401, detail="invalid key")
    payload = await req.json()
    # ack rapide → enqueue → 200
    await enqueue(payload)
    return {"ok": True}
N’effectuez aucun traitement métier synchrone dans le handler HTTP : pas d’appel BDD lourd, pas d’appel API tiers, pas d’envoi d’email. Acceptez vite, faites le travail dans un worker.

Politique de retry

ÉtapeDélaiDétail
Tentative initialet = 0Timeout HTTP côté Fluximmo
Retries immédiatst + ~quelques s2 retries rapides après échec
Retries longstoutes les 5 min10 retries supplémentaires
DROP~50 min après t = 0Le webhook est définitivement abandonné
Codes HTTP considérés OK : 200, 201, 202, 203, 204, 205. Tout autre code (4xx, 5xx) déclenche un retry. SLO côté client : votre handler doit répondre en 30 à 50 secondes maximum. Au-delà, Fluximmo timeout et entre en retry. Un handler bloquant à 30 s sous charge devient une cascade d’échecs.
Idempotence obligatoire. Vous recevrez parfois le même webhook deux fois (retry après timeout côté réseau alors que le serveur avait déjà accepté). Dédupliquez côté client avec une clé stable, par exemple (advert.flxId, branch, alert_id)branch{ "created", "updated" }, ou (advert.flxId, currentPrice.value, isOnline) si vous voulez aussi capturer les diffs.

Architecture recommandée

Le détail (sizing queue, dead-letter, observabilité, scaling worker) sera couvert dans le playbook Architecture haute volumétrie.

Pour aller plus loin