{"openapi":"3.1.0","info":{"title":"Octave API","version":"1.0.0","description":"API REST pour synchroniser les donn\u00e9es d'une application Octave (programmes, lots, documents et images).\n\n## Authentification\n\n1. Obtenez un `client_id` et un `client_secret` aupr\u00e8s de votre administrateur Octave.\n2. \u00c9changez-les contre un access token via `POST \/oauth\/token`.\n3. Incluez le token : `Authorization: Bearer {access_token}`.\n\n## Tester dans cette interface\n\n1. **POST \/oauth\/token** \u2192 Try it out \u2192 Execute.\n2. Copiez `access_token` dans la r\u00e9ponse.\n3. **Authorize** (cadenas) \u2192 collez le token (sans `Bearer`).\n4. Les autres endpoints affichent alors un corps JSON \u00e9ditable (ou un formulaire fichier pour les uploads)."},"servers":[{"url":"https:\/\/preprod-api.octave.immo\/api","description":"Serveur courant"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Access token obtenu via POST \/oauth\/token (collez uniquement le token, sans le pr\u00e9fixe Bearer)."}},"schemas":{"OAuthTokenRequest":{"type":"object","required":["grant_type","client_id","client_secret"],"properties":{"grant_type":{"type":"string","enum":["client_credentials"]},"client_id":{"type":"string","description":"Identifiant client fourni par Octave"},"client_secret":{"type":"string","description":"Secret client fourni par Octave"}}},"OAuthTokenResponse":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string","example":"Bearer"},"expires_in":{"type":"integer","example":3600}}},"ProgramCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":255,"example":"Grille Malraux Icade Metz v2"},"slug":{"type":"string","maxLength":255,"description":"Optionnel. G\u00e9n\u00e9r\u00e9 depuis name si absent."},"is_active":{"type":"boolean","default":true},"contrat_type":{"type":"string","enum":["non_defini","vefa","vir","asl"],"description":"Type de contrat programme"},"cityscan_enabled":{"type":"boolean","default":false},"maquette_3d_url":{"type":"string","maxLength":2048,"nullable":true}}},"ProgramUpdate":{"type":"object","description":"Mise \u00e0 jour partielle : seuls les champs envoy\u00e9s sont modifi\u00e9s.","properties":{"name":{"type":"string","maxLength":255},"slug":{"type":"string","maxLength":255},"is_active":{"type":"boolean"},"contrat_type":{"type":"string","enum":["non_defini","vefa","vir","asl"]},"cityscan_enabled":{"type":"boolean"},"maquette_3d_url":{"type":"string","maxLength":2048,"nullable":true}}},"LotCreate":{"type":"object","required":["number"],"properties":{"number":{"type":"string","maxLength":50,"example":"B117"},"type":{"type":"string","description":"Type de lot (enum ProductType c\u00f4t\u00e9 Octave)"},"gender":{"type":"string","description":"Genre du lot (enum ProductType)"},"floor":{"type":"string","description":"\u00c9tage (enum FloorType)"},"building_number":{"type":"string","maxLength":50},"tantieme":{"type":"number","format":"float"},"is_active":{"type":"boolean","default":true},"prices":{"type":"array","description":"Prix optionnels \u00e0 cr\u00e9er avec le lot","items":{"$ref":"#\/components\/schemas\/LotPriceInput"}}}},"LotPriceInput":{"type":"object","required":["type","value"],"properties":{"type":{"type":"string","description":"Type de prix Octave","enum":["prix_ttc","prix_ht","prix_immo_ttc","prix_immo_ht","prix_foncier_ttc","prix_foncier_ht","prix_mobilier_ttc","prix_travaux_eligible","mensuel_ttc","mensuel_ht","rentabilite_malraux"],"example":"prix_immo_ttc"},"value":{"type":"number","format":"float","minimum":0,"example":397653}}},"LotPriceCreate":{"type":"object","required":["type","value"],"properties":{"type":{"type":"string","description":"Type de prix Octave","enum":["prix_ttc","prix_ht","prix_immo_ttc","prix_immo_ht","prix_foncier_ttc","prix_foncier_ht","prix_mobilier_ttc","prix_travaux_eligible","mensuel_ttc","mensuel_ht","rentabilite_malraux"],"example":"prix_immo_ttc"},"value":{"type":"number","format":"float","minimum":0,"example":397653},"is_active":{"type":"boolean","default":true}}},"LotPriceUpdate":{"type":"object","properties":{"type":{"type":"string","maxLength":100},"value":{"type":"number","format":"float","minimum":0},"is_active":{"type":"boolean"}}},"LotUpdate":{"type":"object","description":"Mise \u00e0 jour partielle.","properties":{"number":{"type":"string","maxLength":50},"type":{"type":"string"},"gender":{"type":"string"},"floor":{"type":"string"},"building_number":{"type":"string","maxLength":50},"tantieme":{"type":"number","format":"float"},"is_active":{"type":"boolean"}}},"DocumentMetadataUpdate":{"type":"object","description":"Mise \u00e0 jour partielle des m\u00e9tadonn\u00e9es (sans le fichier).","properties":{"type":{"type":"string","maxLength":100,"example":"plaquette"},"name":{"type":"string","maxLength":255,"example":"Plaquette commerciale.pdf"},"order":{"type":"integer","minimum":0,"example":1}}},"ImageMetadataUpdate":{"type":"object","description":"Mise \u00e0 jour partielle des m\u00e9tadonn\u00e9es image.","properties":{"type":{"type":"string","maxLength":100,"example":"perspective"},"order":{"type":"integer","minimum":0,"example":1}}},"Error":{"type":"object","properties":{"message":{"type":"string"}}}}},"security":[{"bearerAuth":[]}],"paths":{"\/oauth\/token":{"post":{"tags":["Authentification"],"summary":"Obtenir un access token","security":[],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/OAuthTokenRequest"},"example":{"grant_type":"client_credentials","client_id":"votre-client-id","client_secret":"votre-client-secret"}}}},"responses":{"200":{"description":"Token \u00e9mis","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/OAuthTokenResponse"}}}},"422":{"description":"Identifiants invalides","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/v1\/programs":{"get":{"tags":["Programmes"],"summary":"Lister les programmes","parameters":[{"name":"per_page","in":"query","schema":{"type":"integer","default":25,"maximum":100}}],"responses":{"200":{"description":"Liste pagin\u00e9e"},"401":{"description":"Non authentifi\u00e9"}}},"post":{"tags":["Programmes"],"summary":"Cr\u00e9er un programme","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ProgramCreate"},"example":{"name":"Grille Malraux Icade Metz v2","is_active":true,"cityscan_enabled":false}}}},"responses":{"201":{"description":"Programme cr\u00e9\u00e9"},"401":{"description":"Non authentifi\u00e9"},"422":{"description":"Donn\u00e9es invalides"}}}},"\/v1\/programs\/export":{"get":{"tags":["Programmes"],"summary":"Exporter les programmes","responses":{"200":{"description":"Export complet"},"401":{"description":"Non authentifi\u00e9"}}}},"\/v1\/programs\/{program}":{"get":{"tags":["Programmes"],"summary":"Consulter un programme","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"},"description":"Token du programme"}],"responses":{"200":{"description":"Programme"},"401":{"description":"Non authentifi\u00e9"},"404":{"description":"Introuvable"}}},"patch":{"tags":["Programmes"],"summary":"Mettre \u00e0 jour un programme","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ProgramUpdate"},"example":{"name":"R\u00e9sidence Les Jardins \u2014 Phase 2","is_active":true}}}},"responses":{"200":{"description":"Programme mis \u00e0 jour"},"401":{"description":"Non authentifi\u00e9"},"404":{"description":"Introuvable"},"422":{"description":"Donn\u00e9es invalides"}}},"delete":{"tags":["Programmes"],"summary":"Supprimer un programme","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Supprim\u00e9"},"401":{"description":"Non authentifi\u00e9"},"404":{"description":"Introuvable"}}}},"\/v1\/programs\/{program}\/lots":{"get":{"tags":["Lots"],"summary":"Lister les lots","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"per_page","in":"query","schema":{"type":"integer","default":50,"maximum":200}}],"responses":{"200":{"description":"Liste pagin\u00e9e"},"401":{"description":"Non authentifi\u00e9"}}},"post":{"tags":["Lots"],"summary":"Cr\u00e9er un lot","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/LotCreate"},"example":{"number":"B117","gender":"appartement","type":"t2","floor":"r+1","building_number":"B","is_active":true,"prices":[{"type":"prix_immo_ttc","value":397653},{"type":"prix_foncier_ttc","value":67775},{"type":"prix_travaux_eligible","value":329878},{"type":"mensuel_ttc","value":1100},{"type":"rentabilite_malraux","value":4.42}]}}}},"responses":{"201":{"description":"Lot cr\u00e9\u00e9"},"401":{"description":"Non authentifi\u00e9"},"422":{"description":"Donn\u00e9es invalides"}}}},"\/v1\/programs\/{program}\/lots\/{lot}":{"get":{"tags":["Lots"],"summary":"Consulter un lot","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"lot","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Lot"},"404":{"description":"Introuvable"}}},"patch":{"tags":["Lots"],"summary":"Mettre \u00e0 jour un lot","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"lot","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/LotUpdate"},"example":{"number":"B211","is_active":false}}}},"responses":{"200":{"description":"Lot mis \u00e0 jour"},"404":{"description":"Introuvable"},"422":{"description":"Donn\u00e9es invalides"}}},"delete":{"tags":["Lots"],"summary":"Supprimer un lot","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"lot","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Supprim\u00e9"},"404":{"description":"Introuvable"}}}},"\/v1\/programs\/{program}\/lots\/{lot}\/prices":{"get":{"tags":["Prix"],"summary":"Lister les prix d'un lot","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"lot","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Liste des prix"},"404":{"description":"Introuvable"}}},"post":{"tags":["Prix"],"summary":"Ajouter un prix \u00e0 un lot","description":"Chaque prix est identifi\u00e9 par son `type` (ex. prix_ttc, prix_immo_ttc, mensuel_ttc). Un lot peut avoir plusieurs prix de types diff\u00e9rents.","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"lot","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/LotPriceCreate"},"example":{"type":"prix_immo_ttc","value":397653}}}},"responses":{"201":{"description":"Prix cr\u00e9\u00e9"},"422":{"description":"Donn\u00e9es invalides"}}}},"\/v1\/programs\/{program}\/lots\/{lot}\/prices\/{price}":{"patch":{"tags":["Prix"],"summary":"Mettre \u00e0 jour un prix","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"lot","in":"path","required":true,"schema":{"type":"string"}},{"name":"price","in":"path","required":true,"schema":{"type":"integer"},"description":"ID du prix"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/LotPriceUpdate"},"example":{"value":400000}}}},"responses":{"200":{"description":"Prix mis \u00e0 jour"},"404":{"description":"Introuvable"}}},"delete":{"tags":["Prix"],"summary":"Supprimer un prix","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"lot","in":"path","required":true,"schema":{"type":"string"}},{"name":"price","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Supprim\u00e9"},"404":{"description":"Introuvable"}}}},"\/v1\/programs\/{program}\/documents":{"get":{"tags":["Documents"],"summary":"Lister les documents d'un programme","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Liste des documents"}}},"post":{"tags":["Documents"],"summary":"Ajouter un document \u00e0 un programme","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["file","type"],"properties":{"file":{"type":"string","format":"binary","description":"Fichier (PDF, max 50 Mo)"},"type":{"type":"string","maxLength":100,"example":"plaquette"},"name":{"type":"string","maxLength":255,"description":"Nom affich\u00e9 (d\u00e9faut : nom du fichier)"},"order":{"type":"integer","minimum":0,"example":1}}}}}},"responses":{"201":{"description":"Document cr\u00e9\u00e9"},"422":{"description":"Donn\u00e9es invalides"}}}},"\/v1\/programs\/{program}\/documents\/{document}":{"get":{"tags":["Documents"],"summary":"Consulter un document","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"document","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Document"}}},"patch":{"tags":["Documents"],"summary":"Mettre \u00e0 jour les m\u00e9tadonn\u00e9es d'un document","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"document","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DocumentMetadataUpdate"},"example":{"name":"Plaquette v2.pdf","order":2}}}},"responses":{"200":{"description":"Document mis \u00e0 jour"},"422":{"description":"Donn\u00e9es invalides"}}},"delete":{"tags":["Documents"],"summary":"Supprimer un document","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"document","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Supprim\u00e9"}}}},"\/v1\/programs\/{program}\/images":{"get":{"tags":["Images"],"summary":"Lister les images d'un programme","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Liste des images"}}},"post":{"tags":["Images"],"summary":"Ajouter une image \u00e0 un programme","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Image (max 20 Mo)"},"type":{"type":"string","maxLength":100,"example":"perspective"}}}}}},"responses":{"201":{"description":"Image cr\u00e9\u00e9e"},"422":{"description":"Donn\u00e9es invalides"}}}},"\/v1\/programs\/{program}\/images\/{image}":{"patch":{"tags":["Images"],"summary":"Mettre \u00e0 jour une image","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"image","in":"path","required":true,"schema":{"type":"integer"},"description":"ID m\u00e9dia Spatie"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ImageMetadataUpdate"},"example":{"type":"fa\u00e7ade","order":1}}}},"responses":{"200":{"description":"Image mise \u00e0 jour"},"422":{"description":"Donn\u00e9es invalides"}}},"delete":{"tags":["Images"],"summary":"Supprimer une image","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"image","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Supprim\u00e9e"}}}},"\/v1\/programs\/{program}\/lots\/{lot}\/documents":{"get":{"tags":["Documents"],"summary":"Lister les documents d'un lot","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"lot","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Liste des documents"}}},"post":{"tags":["Documents"],"summary":"Ajouter un document \u00e0 un lot","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"lot","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"type":"object","required":["file","type"],"properties":{"file":{"type":"string","format":"binary"},"type":{"type":"string","maxLength":100,"example":"plan"},"name":{"type":"string","maxLength":255},"order":{"type":"integer","minimum":0}}}}}},"responses":{"201":{"description":"Document cr\u00e9\u00e9"},"422":{"description":"Donn\u00e9es invalides"}}}},"\/v1\/programs\/{program}\/lots\/{lot}\/documents\/{document}":{"patch":{"tags":["Documents"],"summary":"Mettre \u00e0 jour les m\u00e9tadonn\u00e9es d'un document de lot","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"lot","in":"path","required":true,"schema":{"type":"string"}},{"name":"document","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DocumentMetadataUpdate"},"example":{"type":"plan","order":1}}}},"responses":{"200":{"description":"Document mis \u00e0 jour"},"422":{"description":"Donn\u00e9es invalides"}}},"delete":{"tags":["Documents"],"summary":"Supprimer un document de lot","parameters":[{"name":"program","in":"path","required":true,"schema":{"type":"string"}},{"name":"lot","in":"path","required":true,"schema":{"type":"string"}},{"name":"document","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Supprim\u00e9"}}}}}}