{"openapi":"3.1.0","info":{"title":"API CleanPlus — Réservation en ligne","version":"1.0.0","description":"Créneaux libres, création et suivi de réservations. Heures en Europe/Paris. Documentation : https://cleanplus.app/developpeurs/api","contact":{"email":"contact@cleanplus.app"}},"servers":[{"url":"https://cleanplus.app/api/public/v1"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Clé cp_live_… générée dans Paramètres → Développeurs & API"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object"}}}}},"Slot":{"type":"object","properties":{"date":{"type":"string","format":"date"},"start_time":{"type":"string","example":"09:00"},"end_time":{"type":"string","example":"11:00"},"available_agents_count":{"type":"integer"}}},"Service":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"category":{"type":["string","null"]},"unit_price_ht":{"type":["number","null"]},"unit":{"type":["string","null"]}}},"Booking":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"external_ref":{"type":["string","null"]},"status":{"type":"string","enum":["planifie","en_cours","termine","annule"]},"date":{"type":"string","format":"date"},"start_time":{"type":"string"},"end_time":{"type":"string"},"service":{"type":["string","null"]},"notes":{"type":["string","null"]},"site":{"type":"object"},"customer":{"type":"object"},"agents":{"type":"array","items":{"type":"object"}}}},"BookingCreate":{"type":"object","required":["customer","site","slot"],"properties":{"external_ref":{"type":"string"},"customer":{"type":"object","required":["name","email"],"properties":{"type":{"enum":["particulier","professionnel"]},"name":{"type":"string"},"first_name":{"type":"string"},"company_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"siret":{"type":"string"}}},"site":{"type":"object","required":["address"],"properties":{"name":{"type":"string"},"address":{"type":"string"},"postal_code":{"type":"string"},"city":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"access_instructions":{"type":"string"},"access_codes":{"type":"string"},"surface":{"type":"string"},"premises_type":{"type":"string"}}},"slot":{"type":"object","required":["date","start_time","duration_minutes"],"properties":{"date":{"type":"string","format":"date"},"start_time":{"type":"string"},"duration_minutes":{"type":"integer"}}},"agents_count":{"type":"integer","default":1},"service":{"type":"string"},"notes":{"type":"string"},"attachments":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"name":{"type":"string"}}}}}}}},"paths":{"/availability":{"get":{"summary":"Créneaux libres","description":"Scope availability:read. Plage de 31 jours maximum.","parameters":[{"name":"date_from","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"duration_minutes","in":"query","required":true,"schema":{"type":"integer"}},{"name":"agents_count","in":"query","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Créneaux","content":{"application/json":{"schema":{"type":"object","properties":{"slots":{"type":"array","items":{"$ref":"#/components/schemas/Slot"}}}}}}},"400":{"description":"Données invalides","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Clé invalide","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Droit manquant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de débit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/services":{"get":{"summary":"Catalogue des prestations","description":"Scope availability:read.","responses":{"200":{"description":"Prestations","content":{"application/json":{"schema":{"type":"object","properties":{"services":{"type":"array","items":{"$ref":"#/components/schemas/Service"}}}}}}},"400":{"description":"Données invalides","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Clé invalide","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Droit manquant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de débit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/bookings":{"post":{"summary":"Créer une réservation (client + site + intervention)","description":"Scope bookings:write. En-tête Idempotency-Key obligatoire.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreate"}}}},"responses":{"201":{"description":"Réservation créée","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"}}}},"400":{"description":"Données invalides","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Clé invalide","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Droit manquant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Créneau indisponible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de débit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/bookings/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"summary":"Lire une réservation","description":"Scope bookings:read.","responses":{"200":{"description":"Réservation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"}}}},"400":{"description":"Données invalides","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Clé invalide","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Droit manquant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Introuvable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de débit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"summary":"Reprogrammer / modifier","description":"Scope bookings:write.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"slot":{"type":"object"},"service":{"type":"string"},"notes":{"type":"string"},"access_instructions":{"type":"string"},"access_codes":{"type":"string"}}}}}},"responses":{"200":{"description":"Réservation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"}}}},"400":{"description":"Données invalides","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Clé invalide","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Droit manquant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de débit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/bookings/{id}/cancel":{"post":{"summary":"Annuler","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Réservation annulée","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"}}}},"400":{"description":"Données invalides","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Clé invalide","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Droit manquant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de débit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}