{"openapi":"3.1.0","info":{"title":"axisapps Consultation API","version":"1.0.0","description":"API REST axisapps : calculs astrologiques (thème natal, transits, lunaison) + assistant de consultation en direct (transcription Groq Whisper + analyse Claude).","contact":{"name":"AXIS — Studio d'Applications","email":"contact@axisapps.app"}},"servers":[{"url":"https://api.axisapps.app","description":"Production"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"axisk_live_<32hex>","description":"Clé API au format `axisk_live_…`. Doit être fournie en `Authorization: Bearer <key>`."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["VALIDATION_ERROR","UNAUTHORIZED","FORBIDDEN","NOT_FOUND","CONFLICT","RATE_LIMITED","INTERNAL_ERROR","UPSTREAM_ERROR","SERVICE_UNAVAILABLE"]},"message":{"type":"string"},"details":{}}}}},"BirthInput":{"type":"object","required":["date","time","timezone","latitude","longitude"],"properties":{"date":{"type":"string","format":"date","example":"1985-07-14"},"time":{"type":"string","example":"14:30"},"timezone":{"type":"string","example":"Europe/Paris"},"latitude":{"type":"number","example":48.8566},"longitude":{"type":"number","example":2.3522},"place_name":{"type":"string","example":"Paris, France"}}},"ChartOptions":{"type":"object","properties":{"house_system":{"type":"string","enum":["placidus","koch","equal","whole_sign"],"default":"placidus"},"include_minor_aspects":{"type":"boolean","default":false}}},"Planet":{"type":"object","properties":{"name":{"type":"string","example":"Sun"},"longitude":{"type":"number"},"sign":{"type":"string","example":"Cancer"},"degree":{"type":"integer"},"minute":{"type":"integer"},"house":{"type":"integer"},"retrograde":{"type":"boolean"}}},"House":{"type":"object","properties":{"number":{"type":"integer"},"cusp_longitude":{"type":"number"},"sign":{"type":"string"},"degree":{"type":"integer"},"minute":{"type":"integer"}}},"Aspect":{"type":"object","properties":{"p1":{"type":"string"},"p2":{"type":"string"},"type":{"type":"string","example":"trine"},"orb":{"type":"number"},"applying":{"type":"boolean"}}},"NatalChart":{"type":"object","properties":{"planets":{"type":"array","items":{"$ref":"#/components/schemas/Planet"}},"houses":{"type":"array","items":{"$ref":"#/components/schemas/House"}},"aspects":{"type":"array","items":{"$ref":"#/components/schemas/Aspect"}},"axes":{"type":"object","properties":{"asc":{"type":"object","properties":{"longitude":{"type":"number"},"sign":{"type":"string"}}},"mc":{"type":"object","properties":{"longitude":{"type":"number"},"sign":{"type":"string"}}}}}}},"TransitsData":{"type":"object","properties":{"natal_chart":{"$ref":"#/components/schemas/NatalChart"},"transit_planets":{"type":"array","items":{"$ref":"#/components/schemas/Planet"}},"active_aspects":{"type":"array","items":{"type":"object","properties":{"transit_planet":{"type":"string"},"natal_planet":{"type":"string"},"natal_house":{"type":"integer"},"type":{"type":"string"},"orb":{"type":"number"},"applying":{"type":"boolean"},"exact_date":{"type":"string","format":"date"}}}}}},"Suggestion":{"type":"object","required":["type","title","detail","priority","related_aspects"],"properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["transit_emphasis","natal_pattern","follow_up_question"]},"title":{"type":"string"},"detail":{"type":"string"},"priority":{"type":"string","enum":["high","medium","low"]},"related_aspects":{"type":"array","items":{"type":"string"}},"created_at":{"type":"string","format":"date-time"}}}},"responses":{"ValidationError":{"description":"Payload invalide","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Clé API manquante ou invalide","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Ressource appartenant à un autre client","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Ressource introuvable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Conflit (ex: consultation déjà terminée)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Trop de requêtes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"UpstreamError":{"description":"Erreur côté service tiers (Groq, Anthropic, Lunation)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/api/v1/health":{"get":{"summary":"Healthcheck","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"version":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}}}}}}}},"/api/v1/ping":{"get":{"summary":"Authenticated ping","responses":{"200":{"description":"Authenticated","content":{"application/json":{"schema":{"type":"object","properties":{"pong":{"type":"boolean"},"client_id":{"type":"string","format":"uuid"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/charts/natal":{"post":{"summary":"Calcul de thème natal","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["birth","options"],"properties":{"birth":{"$ref":"#/components/schemas/BirthInput"},"options":{"$ref":"#/components/schemas/ChartOptions"}}}}}},"responses":{"200":{"description":"Thème natal calculé","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NatalChart"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/charts/transits":{"post":{"summary":"Transits du jour pour un thème natal","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["natal"],"properties":{"natal":{"type":"object","properties":{"birth":{"$ref":"#/components/schemas/BirthInput"},"options":{"$ref":"#/components/schemas/ChartOptions"}}},"date":{"type":"string","format":"date"}}}}}},"responses":{"200":{"description":"Transits actifs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransitsData"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/charts/lunation":{"post":{"summary":"Révolution lunaire (mock pour l'instant)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"natal":{"type":"object","properties":{"birth":{"$ref":"#/components/schemas/BirthInput"},"options":{"$ref":"#/components/schemas/ChartOptions"}}},"month":{"type":"string","example":"2026-05"}}}}}},"responses":{"200":{"description":"Lunation mock data"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/consultations/start":{"post":{"summary":"Démarrer une consultation","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["natal"],"properties":{"client_reference":{"type":"string"},"natal":{"type":"object","properties":{"birth":{"$ref":"#/components/schemas/BirthInput"},"options":{"$ref":"#/components/schemas/ChartOptions"}}},"transit_date":{"type":"string","format":"date"},"locale":{"type":"string","default":"fr-FR"},"consultation_context":{"type":"object","properties":{"summary":{"type":"string"},"focus_areas":{"type":"array","items":{"type":"string"}}}}}}}}},"responses":{"201":{"description":"Consultation créée","content":{"application/json":{"schema":{"type":"object","properties":{"consultation_id":{"type":"string","format":"uuid"},"natal_chart":{"$ref":"#/components/schemas/NatalChart"},"transits_today":{"$ref":"#/components/schemas/TransitsData"},"initial_briefing":{"type":"string"},"expires_at":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"502":{"$ref":"#/components/responses/UpstreamError"}}}},"/api/v1/consultations/{id}/audio":{"post":{"summary":"Envoyer un chunk audio","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["audio","chunk_index"],"properties":{"audio":{"type":"string","format":"binary"},"chunk_index":{"type":"integer","minimum":0},"speaker":{"type":"string","enum":["astrologer","client"]}}}}}},"responses":{"200":{"description":"Chunk transcrit (+ éventuelles suggestions)","content":{"application/json":{"schema":{"type":"object","properties":{"consultation_id":{"type":"string","format":"uuid"},"chunk_index":{"type":"integer"},"transcript_partial":{"type":"string"},"transcript_cumulative":{"type":"string"},"new_suggestions":{"type":"array","items":{"$ref":"#/components/schemas/Suggestion"}},"speaker":{"type":"string"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"502":{"$ref":"#/components/responses/UpstreamError"}}}},"/api/v1/consultations/{id}/end":{"post":{"summary":"Terminer une consultation","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"rating":{"type":"integer","minimum":1,"maximum":5},"notes":{"type":"string","maxLength":10000}}}}}},"responses":{"200":{"description":"Consultation terminée + synthèse","content":{"application/json":{"schema":{"type":"object","properties":{"consultation_id":{"type":"string","format":"uuid"},"duration_seconds":{"type":"integer"},"summary":{"type":"string"},"total_suggestions":{"type":"integer"},"rating":{"type":"integer"},"notes":{"type":"string"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"502":{"$ref":"#/components/responses/UpstreamError"}}}}}}