{"openapi":"3.0.3","info":{"title":"API cherchertrouver.immo","version":"1.0.0","description":"API REST d'accès aux annonces immobilières agrégées multi-portails (SeLoger, LeBonCoin, PAP, BienIci et autres). Données du bien, prix, prix au m², DPE/GES, localisation approximative.\n\nConfidentialité : l'API ne redistribue AUCUNE donnée de contact. Le champ `seller_name` est `null` pour les vendeurs particuliers, et la `description` est expurgée des téléphones et emails. Les coordonnées GPS sont arrondies à ~111 m. Pour joindre le vendeur, suivre `external_url` vers la fiche d'origine.","termsOfService":"https://cherchertrouver.immo/cgu","contact":{"name":"Support API","url":"https://cherchertrouver.immo/contact"}},"servers":[{"url":"https://cherchertrouver.immo/api/v1","description":"Production"}],"security":[{"ApiKeyHeader":[]},{"BearerAuth":[]}],"tags":[{"name":"Annonces","description":"Recherche et consultation des annonces"},{"name":"Référentiels","description":"Données de référence (zonage PTZ)"},{"name":"Système","description":"Santé et quotas"}],"paths":{"/ping":{"get":{"tags":["Système"],"summary":"Vérifie la clé et retourne les quotas","operationId":"ping","responses":{"200":{"description":"Clé valide","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ping"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/annonces":{"get":{"tags":["Annonces"],"summary":"Recherche paginée d'annonces","description":"Recherche multi-critères. Pour parcourir en profondeur, préférer `cursor` (pagination O(1)) à `page`. Le quota `items_per_day` ne décompte que les couples (source, reference) NOUVEAUX pour la clé.","operationId":"searchAnnonces","parameters":[{"$ref":"#/components/parameters/q"},{"$ref":"#/components/parameters/type"},{"$ref":"#/components/parameters/transaction"},{"$ref":"#/components/parameters/ville"},{"$ref":"#/components/parameters/cp"},{"$ref":"#/components/parameters/dept"},{"$ref":"#/components/parameters/region"},{"$ref":"#/components/parameters/prix_min"},{"$ref":"#/components/parameters/prix_max"},{"$ref":"#/components/parameters/prix_m2_min"},{"$ref":"#/components/parameters/prix_m2_max"},{"$ref":"#/components/parameters/surface_min"},{"$ref":"#/components/parameters/surface_max"},{"$ref":"#/components/parameters/pieces_min"},{"$ref":"#/components/parameters/chambres_min"},{"$ref":"#/components/parameters/annee_min"},{"$ref":"#/components/parameters/annee_max"},{"$ref":"#/components/parameters/dpe"},{"$ref":"#/components/parameters/ges"},{"$ref":"#/components/parameters/source"},{"$ref":"#/components/parameters/sort"},{"$ref":"#/components/parameters/updated_since"},{"$ref":"#/components/parameters/created_since"},{"$ref":"#/components/parameters/page"},{"$ref":"#/components/parameters/page_size"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"Page de résultats","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnoncePage"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/annonces/feed":{"get":{"tags":["Annonces"],"summary":"Flux complet (changefeed) sans plafond de profondeur","description":"Aspire tout le catalogue sans jamais rater d'annonce. Boucler avec `cursor` : appeler sans cursor, traiter `items`, rappeler avec `?cursor=<next_cursor>`. Quand `has_more=false`, rappeler avec le MÊME cursor pour récupérer les nouvelles annonces.","operationId":"feedAnnonces","parameters":[{"$ref":"#/components/parameters/type"},{"$ref":"#/components/parameters/ville"},{"$ref":"#/components/parameters/dept"},{"$ref":"#/components/parameters/page_size"},{"$ref":"#/components/parameters/cursor"}],"responses":{"200":{"description":"Lot du flux","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnonceFeed"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/annonces/map":{"get":{"tags":["Annonces"],"summary":"Annonces dans une emprise géographique (bbox)","operationId":"mapAnnonces","parameters":[{"name":"bbox","in":"query","required":true,"description":"Emprise au format south,west,north,east (latitudes/longitudes).","schema":{"type":"string","example":"48.80,2.25,48.90,2.42"}},{"$ref":"#/components/parameters/type"},{"$ref":"#/components/parameters/transaction"}],"responses":{"200":{"description":"Points cartographiques","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnonceMap"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/annonces/{source}/{reference}":{"get":{"tags":["Annonces"],"summary":"Détail d'une annonce","operationId":"getAnnonce","parameters":[{"name":"source","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9_-]{1,32}$"}},{"name":"reference","in":"path","required":true,"schema":{"type":"string","maxLength":128}}],"responses":{"200":{"description":"Annonce trouvée","content":{"application/json":{"schema":{"type":"object","properties":{"annonce":{"$ref":"#/components/schemas/Annonce"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/ptz/zone":{"get":{"tags":["Référentiels"],"summary":"Zone PTZ (Abis/A/B1/B2/C) d'une commune","description":"Zonage officiel (arrêté du 5 septembre 2025). Lecture seule.","operationId":"ptzZone","parameters":[{"name":"cp","in":"query","required":true,"description":"Code postal (5 chiffres).","schema":{"type":"string","pattern":"^[0-9]{5}$","example":"75011"}}],"responses":{"200":{"description":"Zone trouvée","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PtzZone"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}}},"components":{"securitySchemes":{"ApiKeyHeader":{"type":"apiKey","in":"header","name":"X-Api-Key","description":"Clé API (préfixe imk_...)."},"BearerAuth":{"type":"http","scheme":"bearer","description":"Alternative : Authorization: Bearer <clé>."}},"parameters":{"q":{"name":"q","in":"query","description":"Recherche plein texte (titre + description).","schema":{"type":"string","maxLength":120}},"type":{"name":"type","in":"query","description":"Type de bien (Appartement, Maison, Terrain...).","schema":{"type":"string","maxLength":40}},"transaction":{"name":"transaction","in":"query","schema":{"type":"string","enum":["vente","location"]}},"ville":{"name":"ville","in":"query","description":"Une ou plusieurs villes (séparées par des virgules, max 8).","schema":{"type":"string","maxLength":120}},"cp":{"name":"cp","in":"query","description":"Code postal.","schema":{"type":"string","maxLength":16}},"dept":{"name":"dept","in":"query","description":"Département.","schema":{"type":"string","maxLength":3}},"region":{"name":"region","in":"query","schema":{"type":"string","maxLength":64}},"prix_min":{"name":"prix_min","in":"query","schema":{"type":"integer","minimum":0}},"prix_max":{"name":"prix_max","in":"query","schema":{"type":"integer","minimum":0}},"prix_m2_min":{"name":"prix_m2_min","in":"query","schema":{"type":"integer","minimum":0}},"prix_m2_max":{"name":"prix_m2_max","in":"query","schema":{"type":"integer","minimum":0}},"surface_min":{"name":"surface_min","in":"query","schema":{"type":"number","minimum":0}},"surface_max":{"name":"surface_max","in":"query","schema":{"type":"number","minimum":0}},"pieces_min":{"name":"pieces_min","in":"query","schema":{"type":"integer","minimum":0}},"chambres_min":{"name":"chambres_min","in":"query","schema":{"type":"integer","minimum":0}},"annee_min":{"name":"annee_min","in":"query","schema":{"type":"integer","minimum":1700,"maximum":2100}},"annee_max":{"name":"annee_max","in":"query","schema":{"type":"integer","minimum":1700,"maximum":2100}},"dpe":{"name":"dpe","in":"query","description":"Classes DPE acceptées (répétable ou CSV).","schema":{"type":"array","items":{"type":"string","enum":["A","B","C","D","E","F","G"]}},"style":"form","explode":false},"ges":{"name":"ges","in":"query","description":"Classes GES acceptées (répétable ou CSV).","schema":{"type":"array","items":{"type":"string","enum":["A","B","C","D","E","F","G"]}},"style":"form","explode":false},"source":{"name":"source","in":"query","description":"Portée : all (défaut), interne (annonces publiées par nous), scraped.","schema":{"type":"string","enum":["all","interne","scraped"]}},"sort":{"name":"sort","in":"query","schema":{"type":"string","enum":["recent","price_asc","price_desc","surface_desc","pricem2_asc"],"default":"recent"}},"updated_since":{"name":"updated_since","in":"query","description":"Annonces (re-)scrapées depuis cette date (ISO 8601). Pour la veille incrémentale, combiner avec sort=recent.","schema":{"type":"string","format":"date-time"}},"created_since":{"name":"created_since","in":"query","description":"Annonces publiées sur le portail source depuis cette date (ISO 8601).","schema":{"type":"string","format":"date-time"}},"page":{"name":"page","in":"query","description":"Numéro de page (1..1000). Préférer cursor au-delà de 50.","schema":{"type":"integer","minimum":1,"maximum":1000}},"page_size":{"name":"page_size","in":"query","description":"Taille de page (max 100).","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},"cursor":{"name":"cursor","in":"query","description":"Curseur opaque de pagination (fourni par next_cursor).","schema":{"type":"string","maxLength":500}}},"responses":{"BadRequest":{"description":"Paramètres invalides","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Clé API manquante ou invalide","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Ressource introuvable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Débit ou quota journalier dépassé","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Message lisible."},"code":{"type":"string","description":"Code machine (BAD_REQUEST, NOT_FOUND...)."}}},"Ping":{"type":"object","properties":{"ok":{"type":"boolean"},"api_key_name":{"type":"string"},"tier":{"type":"string"},"rate_limit_per_sec":{"type":"integer"},"rate_limit_per_min":{"type":"integer"},"items_per_day":{"type":"integer"},"server_time":{"type":"string","format":"date-time"}}},"PtzZone":{"type":"object","properties":{"zone":{"type":"string","example":"Abis"},"codePostal":{"type":"string","example":"75011"},"source":{"type":"string"}}},"Annonce":{"type":"object","description":"Annonce agrégée. Aucun contact : seller_name est null pour les particuliers, description expurgée des tél/emails, coordonnées arrondies à ~111 m.","properties":{"source":{"type":"string"},"reference":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"},"transaction_type":{"type":"string","enum":["vente","location"]},"price":{"type":"number","nullable":true},"price_per_m2":{"type":"number","nullable":true},"price_per_m2_color":{"type":"string","nullable":true},"price_label":{"type":"string","nullable":true},"surface":{"type":"number","nullable":true},"land_surface":{"type":"number","nullable":true},"living_room_surface":{"type":"number","nullable":true},"rooms":{"type":"integer","nullable":true},"bedrooms":{"type":"integer","nullable":true},"bathrooms":{"type":"integer","nullable":true},"shower_rooms":{"type":"integer","nullable":true},"toilets":{"type":"integer","nullable":true},"kitchen":{"type":"string","nullable":true},"year_built":{"type":"integer","nullable":true},"elevator":{"type":"boolean","nullable":true},"parking":{"type":"boolean","nullable":true},"parking_interior":{"type":"boolean","nullable":true},"parking_exterior":{"type":"boolean","nullable":true},"cellar":{"type":"boolean","nullable":true},"garden":{"type":"boolean","nullable":true},"seller_type":{"type":"string","enum":["Pro","Particulier"],"nullable":true},"seller_name":{"type":"string","nullable":true,"description":"Nom de l'agence (pro). null pour un vendeur particulier (donnée personnelle non exposée)."},"real_estate_network":{"type":"string","nullable":true},"exclusive":{"type":"boolean","nullable":true},"city":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true},"department":{"type":"string","nullable":true},"region":{"type":"string","nullable":true},"latitude":{"type":"number","nullable":true,"description":"Arrondie à ~111 m."},"longitude":{"type":"number","nullable":true,"description":"Arrondie à ~111 m."},"dpe":{"type":"string","enum":["A","B","C","D","E","F","G"],"nullable":true},"ges":{"type":"string","enum":["A","B","C","D","E","F","G"],"nullable":true},"dpe_value":{"type":"number","nullable":true,"description":"kWh/m²/an."},"ges_value":{"type":"number","nullable":true,"description":"kg CO2/m²/an."},"dpe_chart_url":{"type":"string","nullable":true},"ges_chart_url":{"type":"string","nullable":true},"legal_info":{"type":"object","nullable":true},"images":{"type":"array","items":{"type":"string","format":"uri"}},"images_count":{"type":"integer"},"description":{"type":"string","nullable":true,"description":"Texte libre expurgé des téléphones et emails."},"external_url":{"type":"string","format":"uri","description":"Lien vers la fiche d'origine (pour joindre le vendeur)."},"video_url":{"type":"string","nullable":true},"virtual_tour_url":{"type":"string","nullable":true},"published_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true},"is_internal":{"type":"boolean"},"dedup_key":{"type":"string","nullable":true},"sources":{"type":"array","nullable":true,"items":{"type":"string"}}}},"AnnonceMapPoint":{"type":"object","properties":{"source":{"type":"string"},"reference":{"type":"string"},"latitude":{"type":"number","nullable":true},"longitude":{"type":"number","nullable":true},"price":{"type":"number","nullable":true},"price_per_m2":{"type":"number","nullable":true},"price_per_m2_color":{"type":"string","nullable":true},"surface":{"type":"number","nullable":true},"type":{"type":"string","nullable":true},"title":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true},"rooms":{"type":"integer","nullable":true},"image":{"type":"string","nullable":true},"is_internal":{"type":"boolean"}}},"AnnoncePage":{"type":"object","properties":{"page":{"type":"integer"},"page_size":{"type":"integer"},"has_more":{"type":"boolean"},"next_cursor":{"type":"string","nullable":true},"items":{"type":"array","items":{"$ref":"#/components/schemas/Annonce"}}}},"AnnonceFeed":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Annonce"}},"count":{"type":"integer"},"has_more":{"type":"boolean"},"next_cursor":{"type":"string","nullable":true}}},"AnnonceMap":{"type":"object","properties":{"bbox":{"type":"array","items":{"type":"number"}},"total":{"type":"integer"},"capped":{"type":"boolean"},"items":{"type":"array","items":{"$ref":"#/components/schemas/AnnonceMapPoint"}}}}}}}