Stream EstateStream Estate
Guides

Filtrage

Composer un arbre criteria pour POST /properties

Le body de POST /properties repose sur un seul champ criteria — un arbre récursif dont chaque nœud prend exactement l'une de ces trois formes :

  • une feuille Filters (un regroupement plat de filtres par facette — le cas le plus courant) ;
  • un nœud AND { "and": [/* enfants */] } — tous les enfants doivent correspondre ;
  • un nœud OR { "or": [/* enfants */] } — au moins un enfant doit correspondre.

Omettez criteria pour faire correspondre toutes les properties.

Forme du body

{
  "criteria": { /* CriteriaNode */ },
  "paginationType": "PAGE",
  "page": 1,
  "size": 20
}
ChampTypeValeur
criteriaCriteriaNode | nullFeuille Filters, nœud and, ou nœud or.
paginationTypeenum"PAGE" (défaut) ou "CURSOR". Voir Pagination.
pageintegerHonoré uniquement en PAGE. Défaut 1, minimum 1.
cursorstring | nullHonoré uniquement en CURSOR. Renvoyez la valeur reçue dans la réponse précédente.
sizeinteger0–100. Défaut 10. Avec 0, la réponse ne contient aucun bien, seulement leur nombre : voir Compter sans récupérer les biens.
sortobjectDirective de tri (champ + direction).

La feuille Filters

Une feuille regroupe les filtres par facette (toutes combinées en AND au sein de la feuille) :

FacetteDTOCible
propertyPropertyFacetFiltersDTOtype, transaction, pricing, areas, locations, unit, building, amenities, body.
publisherPublisherFiltersDTOtype, mandate, references, hasEmail, hasPhone (toutes les clauses portent sur le même publisher).
listingsListingsFiltersDTOurl, sources, marketing, expiredAt, priceCoherent (toutes les clauses portent sur le même listing, sauf priceCoherent, jugé au niveau de la property).
datesDatesFiltersDTOcreatedAt, updatedAt.

Pour la liste exhaustive des sous-champs de chaque facette (par exemple property.pricing.displayed, property.areas.displayed, property.unit.rooms, property.locations.in, etc.), voir /api-reference — la référence est régénérée à chaque build depuis la spec live.

Masques par défaut

Deux populations sont exclues des résultats tant que le filtre correspondant n'est pas posé :

  • Annonces expirées — masquées par défaut. Poser listings.expiredAt les inclut (restreintes à la plage demandée le cas échéant).
  • Prix incohérents — les properties dont toutes les annonces ont un prix jugé incohérent avec le marché local sont masquées par défaut : listings.priceCoherent vaut true implicitement. Envoyez false pour ne retourner que ces properties. Les biens au verdict indéterminé restent visibles dans tous les cas.

Exemple — feuille simple

Appartements à vendre à Paris entre 200k€ et 600k€, 3 à 5 pièces, avec balcon :

curl -X POST "https://api-v2.stream.estate/properties" \
  -H "X-API-KEY: <votre_clé>" \
  -H "Content-Type: application/json" \
  -d '{
    "criteria": {
      "property": {
        "type":      { "in": ["FLAT"] },
        "transaction": { "type": "SELL" },
        "pricing":   { "displayed": { "gte": 200000, "lte": 600000 } },
        "areas":     { "displayed": { "gte": 50 } },
        "unit":      {
          "rooms":    { "gte": 3, "lte": 5 },
          "features": { "in": ["BALCONY"] }
        },
        "locations": {
          "countryCode": "FR",
          "in": { "uniqueCodes": ["75056"] }
        }
      }
    },
    "paginationType": "PAGE",
    "page": 1,
    "size": 20
  }'

Recherche texte

property.body.title et property.body.description filtrent sur le texte des annonces. Chacun prend un objet à deux listes :

{
  "criteria": {
    "property": {
      "body": {
        "description": {
          "in":  ["à rénover", "travaux"],
          "nin": ["bail commercial", "ehpad"]
        }
      }
    }
  },
  "size": 20
}
  • Chaque entrée est une phrase : ses mots doivent apparaître côte à côte, dans cet ordre. "division possible" ne retient pas une annonce où les deux mots sont à trois paragraphes l'un de l'autre. Un mot seul est une phrase d'un mot.
  • Casse et accents sont ignorés : "A RENOVER" et "à rénover" sont la même requête.
  • in — le texte doit contenir au moins une des phrases (un OU). Pour exiger deux phrases à la fois, mettez une feuille par phrase dans un nœud and.
  • nin — le texte ne doit contenir aucune des phrases.
  • Jusqu'à 25 phrases par liste. Les deux listes sont facultatives.

Une chaîne nue ("description": "travaux") est refusée avec un 400. Pour retrouver le résultat que renvoyait "division possible" — l'un ou l'autre des mots — envoyez { "in": ["division", "possible"] } ; pour la phrase, { "in": ["division possible"] }.

Norme du diagnostic énergétique

property.unit.diagnostic.standard filtre sur la norme réglementaire du DPE : FR_DPE_2006 pour un DPE établi avant le 1ᵉʳ juillet 2021, FR_DPE_2021 à partir de cette date. Même triplet de clauses que unit.condition :

ClauseEffet
inStrict : la norme doit figurer dans la liste. Les biens dont la norme est inconnue sont exclus.
ninLa norme ne doit pas figurer dans la liste. Les biens dont la norme est inconnue passent.
inOrMissingLa norme figure dans la liste ou est inconnue : conserve les biens dont la source n'a pas indiqué la norme.

Une valeur hors liste est refusée avec un 400 qui nomme les valeurs acceptées. Le critère s'écrit tel quel dans le criteria d'une alerte.

Biens classés A à C dont le DPE suit la norme 2021, ou dont la norme n'est pas indiquée :

{
  "criteria": {
    "property": {
      "unit": {
        "diagnostic": {
          "standard": { "inOrMissing": ["FR_DPE_2021"] },
          "scores": [ { "type": "ENERGY_CONSUMPTION", "rating": ["A", "B", "C"] } ]
        }
      }
    }
  },
  "size": 20
}

Nœuds AND / OR

Pour combiner plusieurs feuilles, utilisez and: ou or: — chaque enfant est lui-même un CriteriaNode (donc une feuille, un autre and, ou un autre or). Chaque tableau contient entre 2 et 10 nœuds enfants, et la profondeur d'imbrication n'est pas limitée : pour combiner plus de dix branches, imbriquez un nœud supplémentaire.

{
  "criteria": {
    "or": [
      {
        "property": {
          "type": { "in": ["FLAT"] },
          "areas": { "displayed": { "gte": 60 } }
        }
      },
      {
        "property": {
          "type": { "in": ["HOUSE"] },
          "areas": { "displayed": { "gte": 100 }, "land": { "gte": 300 } }
        }
      }
    ]
  },
  "paginationType": "PAGE",
  "size": 20
}

Combien d'enfants par nœud

Un tableau and ou or doit contenir au moins 2 et au plus 10 enfants. La règle est la même pour les deux opérateurs, et elle s'applique à chaque nœud indépendamment. En dehors de ces bornes, la requête est refusée avec un 422 :

Enfants dans le tableauRésultat
0 ou 1422 — or must contain at least 2 children (ou and must contain at least 2 children)
2 à 10accepté
11 ou plus422 — or must contain at most 10 children (ou and must contain at most 10 children)

Un nœud à un seul enfant n'a de toute façon pas d'effet : remplacez-le par son enfant. Pour combiner plus de dix branches, imbriquez — la profondeur, elle, n'est pas bornée :

{
  "criteria": {
    "or": [
      { "or": [ /* 10 branches */ ] },
      { "or": [ /* 10 branches de plus */ ] }
    ]
  }
}

Réponse

Au format JSON:API (défaut), les biens sont dans data[], la pagination dans meta, et les annonces / annonceurs complets dans included :

{
  "data": [ /* ressources Property (type, id, attributes, relationships) */ ],
  "meta": {
    "totalItems": 1847,
    "hasNextPage": true,
    "cursor": "eyJzb3J0Ijpb..."
  },
  "links": { "self": "/properties" },
  "included": [ /* Listing, Publisher, PropertyPublisher, Source */ ]
}
  • meta.totalItems — nombre total de matches. En mode PAGE, il est plafonné à 10 000.
  • meta.hasNextPage — true s'il reste des résultats.
  • meta.cursor — opaque, à renvoyer tel quel dans la requête suivante en mode CURSOR. null en mode PAGE.

Chaque résultat de recherche contient déjà l'intégralité du bien : exactement le même contenu que GET /properties/{id} (property, publishers[], listings[]). Inutile d'appeler GET /properties/{id} pour compléter un résultat ; cet appel sert uniquement à récupérer un bien dont vous connaissez déjà l'identifiant.

Version 0.14.289Dernière mise à jour

Sur cette page