{"openapi":"3.1.0","info":{"title":"Spiritus","version":"0.1.0"},"paths":{"/api/auth/config":{"get":{"tags":["auth"],"summary":"Auth Config","description":"Return auth configuration so the frontend knows which login to show.","operationId":"auth_config_api_auth_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthConfigResponse"}}}}}}},"/api/auth/register":{"post":{"tags":["auth"],"summary":"Register","description":"Create a new password-based account via SuperTokens.","operationId":"register_api_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/password-login":{"post":{"tags":["auth"],"summary":"Password Login","description":"Login with email + password via SuperTokens.","operationId":"password_login_api_auth_password_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordLoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/verify-email":{"post":{"tags":["auth"],"summary":"Verify Email","description":"Consume a verification token and mark the email as verified.","operationId":"verify_email_api_auth_verify_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/forgot-password":{"post":{"tags":["auth"],"summary":"Forgot Password","description":"Send a password reset email. Always returns 200 to prevent email enumeration.","operationId":"forgot_password_api_auth_forgot_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/admin/mint-reset-link":{"post":{"tags":["auth"],"summary":"Admin Mint Reset Link","description":"Admin-only: mint a password reset URL to DM to a user directly.\n\nBypasses email delivery entirely — useful when iCloud/Outlook filters\ndrop the standard reset email or when onboarding a user out-of-band.","operationId":"admin_mint_reset_link_api_auth_admin_mint_reset_link_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Mint Reset Link Api Auth Admin Mint Reset Link Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/reset-password":{"post":{"tags":["auth"],"summary":"Reset Password","description":"Consume a reset token and set a new password. Force-logs out all sessions.","operationId":"reset_password_api_auth_reset_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/login":{"post":{"tags":["auth"],"summary":"Login","description":"Email-only login — available in dev mode only.","operationId":"login_api_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/google":{"post":{"tags":["auth"],"summary":"Google Login","description":"Google OAuth login — verify Google ID token and create session.","operationId":"google_login_api_auth_google_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleLoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/oauth":{"post":{"tags":["auth"],"summary":"Oauth Login","description":"Universal OAuth login for Microsoft, GitHub, Apple.","operationId":"oauth_login_api_auth_oauth_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthLoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/session/refresh":{"post":{"tags":["auth"],"summary":"Refresh Session Endpoint","description":"Rotate a SuperTokens session using a desktop-held refresh token.\n\nUsed by native clients (ZugaClaw, ZugaGamer) that have no cookie jar.\nWeb clients don't hit this — their refresh flows through SuperTokens'\ncookie-based endpoint.\n\nRefresh tokens ROTATE on every successful call: the returned\nrefresh_token REPLACES the one sent. Clients must persist the new pair.\nOn 401, the client should clear stored tokens and prompt re-login.","operationId":"refresh_session_endpoint_api_auth_session_refresh_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/session/for-desktop":{"post":{"tags":["auth"],"summary":"Mint Session For Desktop","description":"Mint a fresh SuperTokens session for a user already authed on the web.\n\nWhen ZugaClaw / ZugaGamer launch `zugabot.ai/login?redirect=<proto>://...`\nand the user is already signed in on the web, LoginView calls this with\nthe existing Bearer token. We issue a fresh {access, refresh} pair so the\ndesktop app has what it needs — no re-entering credentials.\n\nRequires a valid Bearer token; the minted pair is bound to the same user.","operationId":"mint_session_for_desktop_api_auth_session_for_desktop_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshResponse"}}}}}}},"/api/auth/logout":{"post":{"tags":["auth"],"summary":"Logout","description":"Revoke the current session.","operationId":"logout_api_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Logout Api Auth Logout Post"}}}}}}},"/api/auth/me":{"get":{"tags":["auth"],"summary":"Me","description":"Return info about the currently authenticated user.","operationId":"me_api_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}}}},"/api/auth/change-password":{"post":{"tags":["auth"],"summary":"Change Password","description":"Change password for the currently authenticated user.","operationId":"change_password_api_auth_change_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/onboarding":{"get":{"tags":["auth"],"summary":"Get Onboarding","description":"Check if the user has completed app-level onboarding.","operationId":"get_onboarding_api_auth_onboarding_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Onboarding Api Auth Onboarding Get"}}}}}}},"/api/auth/bg-theme-pref":{"get":{"tags":["auth"],"summary":"Get Bg Theme Pref Route","description":"Return the users account-scoped wallpaper theme id (None = unset).","operationId":"get_bg_theme_pref_route_api_auth_bg_theme_pref_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Bg Theme Pref Route Api Auth Bg Theme Pref Get"}}}}}},"patch":{"tags":["auth"],"summary":"Patch Bg Theme Pref Route","description":"Persist the users account-scoped wallpaper theme id.","operationId":"patch_bg_theme_pref_route_api_auth_bg_theme_pref_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BgThemePrefBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Patch Bg Theme Pref Route Api Auth Bg Theme Pref Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/onboarding/complete":{"post":{"tags":["auth"],"summary":"Complete Onboarding","description":"Mark app-level onboarding as completed.","operationId":"complete_onboarding_api_auth_onboarding_complete_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Complete Onboarding Api Auth Onboarding Complete Post"}}}}}}},"/api/auth/onboarding/reset":{"post":{"tags":["auth"],"summary":"Reset Onboarding","description":"Reset app-level onboarding so the user can replay it.","operationId":"reset_onboarding_api_auth_onboarding_reset_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Reset Onboarding Api Auth Onboarding Reset Post"}}}}}}},"/api/auth/admin/reset-user":{"post":{"tags":["auth"],"summary":"Admin Reset User","description":"Admin: reset a user's onboarding and role from ALLOWED_EMAILS.","operationId":"admin_reset_user_api_auth_admin_reset_user_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminResetRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Reset User Api Auth Admin Reset User Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/admin/delete-user":{"post":{"tags":["auth"],"summary":"Admin Delete User","description":"Admin: hard-delete any user. Requires body.confirm to exactly match\nbody.email (typo protection; prevents fat-finger deletes from curl/Postman).","operationId":"admin_delete_user_api_auth_admin_delete_user_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminDeleteUserRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Delete User Api Auth Admin Delete User Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/users/me":{"delete":{"tags":["auth"],"summary":"Delete Own Account","description":"Self-serve full account deletion (WA MHMDA / CA CMIA deletion right).\n\nHard-deletes the calling user's account: SuperTokens credentials, every\nuser_id-bearing row in _USER_DEPENDENT_TABLES (including spiritus_consents),\nand the app user row. Purge is immediate — well inside the 30-day SLA the\nprivacy policy promises (WA MHMDA allows 45 days).\n\nRequires body.confirm to exactly match the account email so a stray client\ncall can't wipe an account. The session is revoked as part of deletion, so\nthe caller is logged out everywhere when this returns.","operationId":"delete_own_account_api_auth_users_me_delete","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SelfDeleteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Delete Own Account Api Auth Users Me Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/health/live":{"get":{"summary":"Health Live","operationId":"health_live_api_health_live_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/domain/manifest":{"get":{"tags":["domain-outcome-contract"],"summary":"Domain Manifest","operationId":"domain_manifest_domain_manifest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/domain/summary":{"get":{"tags":["domain-outcome-contract"],"summary":"Domain Summary","description":"Domain outcome snapshot. Always returns HTTP 200 (contract requirement).","operationId":"domain_summary_domain_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/lifecycle/shutdown":{"post":{"tags":["lifecycle"],"summary":"Lifecycle Shutdown","description":"Orchestrator-initiated graceful shutdown. Requires LIFECYCLE_SECRET header.","operationId":"lifecycle_shutdown_api_spiritus_lifecycle_shutdown_post","parameters":[{"name":"x-lifecycle-secret","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Lifecycle-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/lifecycle/status":{"get":{"tags":["lifecycle"],"summary":"Lifecycle Status","description":"Current lifecycle state.","operationId":"lifecycle_status_api_spiritus_lifecycle_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/mood":{"post":{"tags":["life"],"summary":"Log Mood","description":"Log a mood entry. Rate-limited to 1 entry per 6-hour window.","operationId":"log_mood_api_spiritus_mood_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoodLogRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoodLogResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["life"],"summary":"Get History","description":"Get mood history for the last N days.","operationId":"get_history_api_spiritus_mood_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":7,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoodHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/mood/streak":{"get":{"tags":["life"],"summary":"Get Streak","description":"Get current consecutive-day streak and total log count.","operationId":"get_streak_api_spiritus_mood_streak_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoodStreakResponse"}}}}}}},"/api/spiritus/journal/prompt":{"get":{"tags":["life-journal"],"summary":"Get Daily Prompt","description":"Get today's guided journal prompt (Pennebaker-informed, rotating by category).","operationId":"get_daily_prompt_api_spiritus_journal_prompt_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/journal":{"post":{"tags":["life-journal"],"summary":"Create Journal Entry","description":"Create a new journal entry.","operationId":"create_journal_entry_api_spiritus_journal_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JournalCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JournalEntryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["life-journal"],"summary":"List Journal Entries","description":"List journal entries with pagination. Returns brief previews.","operationId":"list_journal_entries_api_spiritus_journal_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":30,"title":"Days"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JournalListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/journal/export":{"get":{"tags":["life-journal"],"summary":"Export Journal","description":"Export journal entries as a ZIP of markdown files or JSON.","operationId":"export_journal_api_spiritus_journal_export_get","parameters":[{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(markdown|json|obsidian)$","default":"markdown","title":"Format"}},{"name":"start","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start date YYYY-MM-DD","title":"Start"},"description":"Start date YYYY-MM-DD"},{"name":"end","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End date YYYY-MM-DD","title":"End"},"description":"End date YYYY-MM-DD"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/journal/{entry_id}/export":{"get":{"tags":["life-journal"],"summary":"Export Single Entry","description":"Export a single journal entry as Markdown (.md) or JSON file.","operationId":"export_single_entry_api_spiritus_journal__entry_id__export_get","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(markdown|json|obsidian)$","default":"markdown","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/journal/{entry_id}":{"get":{"tags":["life-journal"],"summary":"Get Journal Entry","description":"Get a single journal entry with all reflections.","operationId":"get_journal_entry_api_spiritus_journal__entry_id__get","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JournalEntryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["life-journal"],"summary":"Delete Journal Entry","description":"Delete a journal entry and all its reflections (cascade).","operationId":"delete_journal_entry_api_spiritus_journal__entry_id__delete","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/journal/{entry_id}/reflect":{"post":{"tags":["life-journal"],"summary":"Reflect On Entry","description":"Generate an AI reflection on a journal entry. Costs credits.","operationId":"reflect_on_entry_api_spiritus_journal__entry_id__reflect_post","parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"integer","title":"Entry Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JournalReflectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/habits":{"get":{"tags":["life-habits"],"summary":"List Habits","description":"List all habit definitions. Auto-seeds presets on first call.","operationId":"list_habits_api_spiritus_habits_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/HabitDefinitionResponse"},"type":"array","title":"Response List Habits Api Spiritus Habits Get"}}}}}},"post":{"tags":["life-habits"],"summary":"Create Habit","description":"Create a custom habit.","operationId":"create_habit_api_spiritus_habits_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HabitCreateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HabitDefinitionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/habits/weekly":{"get":{"tags":["life-habits"],"summary":"Get Weekly Targets","description":"Get weekly target progress for all habits that have a target set.","operationId":"get_weekly_targets_api_spiritus_habits_weekly_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeeklyTargetsResponse"}}}}}}},"/api/spiritus/habits/{habit_id}":{"patch":{"tags":["life-habits"],"summary":"Update Habit","description":"Update a habit definition (rename, toggle active, reorder).","operationId":"update_habit_api_spiritus_habits__habit_id__patch","parameters":[{"name":"habit_id","in":"path","required":true,"schema":{"type":"integer","title":"Habit Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HabitUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HabitDefinitionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["life-habits"],"summary":"Delete Habit","description":"Delete a custom habit. Presets can only be deactivated, not deleted.","operationId":"delete_habit_api_spiritus_habits__habit_id__delete","parameters":[{"name":"habit_id","in":"path","required":true,"schema":{"type":"integer","title":"Habit Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/habits/{habit_id}/escalate":{"post":{"tags":["life-habits"],"summary":"Escalate Habit","description":"Bump a habit's target one step toward its full target.\n\nPsychology: BJ Fogg's Tiny Habits — start absurdly small, escalate only\nwhen the user feels ready. Never risk failure.","operationId":"escalate_habit_api_spiritus_habits__habit_id__escalate_post","parameters":[{"name":"habit_id","in":"path","required":true,"schema":{"type":"integer","title":"Habit Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HabitDefinitionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/habits/log":{"post":{"tags":["life-habits"],"summary":"Log Habit","description":"Log or update a habit for a date. Upserts — same habit+date updates the existing log.","operationId":"log_habit_api_spiritus_habits_log_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HabitLogRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HabitLogResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/habits/log/{habit_id}/{log_date}":{"delete":{"tags":["life-habits"],"summary":"Uncheck Habit","description":"Remove a habit log for a specific date (uncheck).","operationId":"uncheck_habit_api_spiritus_habits_log__habit_id___log_date__delete","parameters":[{"name":"habit_id","in":"path","required":true,"schema":{"type":"integer","title":"Habit Id"}},{"name":"log_date","in":"path","required":true,"schema":{"type":"string","format":"date","title":"Log Date"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/habits/reset/today":{"delete":{"tags":["life-habits"],"summary":"Reset Today","description":"Delete all habit logs for today — uncheck everything.","operationId":"reset_today_api_spiritus_habits_reset_today_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/habits/reset/insights":{"delete":{"tags":["life-habits"],"summary":"Reset Insights Only","description":"Delete past AI insight rows so the 7-day cooldown clears.\nHabit logs are preserved — this is for unblocking after a stale or\nbad insight without losing tracking history.","operationId":"reset_insights_only_api_spiritus_habits_reset_insights_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/habits/reset/history":{"delete":{"tags":["life-habits"],"summary":"Reset All History","description":"Delete ALL habit logs AND past AI insights for this user. Streaks\nreset to zero, and the 7-day insight cooldown also resets so a fresh\nhistory can be analysed without being blocked by a stale insight.","operationId":"reset_all_history_api_spiritus_habits_reset_history_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/habits/reset/day/{log_date}":{"delete":{"tags":["life-habits"],"summary":"Reset Single Day","description":"Delete all habit logs for a single day. Use from the History view\nto remove an entire day (e.g. one bad day skewing the streaks).","operationId":"reset_single_day_api_spiritus_habits_reset_day__log_date__delete","parameters":[{"name":"log_date","in":"path","required":true,"schema":{"type":"string","format":"date","title":"Log Date"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/habits/reset/{habit_id}":{"delete":{"tags":["life-habits"],"summary":"Reset Single Habit","description":"Delete all logs for a single habit. Its streak resets to zero.","operationId":"reset_single_habit_api_spiritus_habits_reset__habit_id__delete","parameters":[{"name":"habit_id","in":"path","required":true,"schema":{"type":"integer","title":"Habit Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/habits/checkin":{"get":{"tags":["life-habits"],"summary":"Get Checkin","description":"Get today's (or a specific date's) check-in view — all habits with their log status.","operationId":"get_checkin_api_spiritus_habits_checkin_get","parameters":[{"name":"date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DailyCheckInResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/habits/history":{"get":{"tags":["life-habits"],"summary":"Get History","description":"Get day-by-day habit history with completion rates.","operationId":"get_history_api_spiritus_habits_history_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":7,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HabitHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/habits/streaks":{"get":{"tags":["life-habits"],"summary":"Get Streaks","description":"Get current and longest streak per habit + overall.","operationId":"get_streaks_api_spiritus_habits_streaks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AllStreaksResponse"}}}}}}},"/api/spiritus/habits/insight":{"post":{"tags":["life-habits"],"summary":"Generate Insight","description":"Generate an AI weekly insight correlating habits with moods. 7-day cooldown.","operationId":"generate_insight_api_spiritus_habits_insight_post","responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HabitInsightResponse"}}}}}}},"/api/spiritus/habits/insights":{"get":{"tags":["life-habits"],"summary":"List Insights","description":"List past AI habit insights.","operationId":"list_insights_api_spiritus_habits_insights_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HabitInsightListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/goals/templates":{"get":{"tags":["life-goals"],"summary":"List Templates","description":"List available goal templates, marking which ones are already adopted.","operationId":"list_templates_api_spiritus_goals_templates_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/GoalTemplateResponse"},"type":"array","title":"Response List Templates Api Spiritus Goals Templates Get"}}}}}}},"/api/spiritus/goals/from-template":{"post":{"tags":["life-goals"],"summary":"Create From Template","description":"Create a goal from a template, auto-link matching habits, and seed milestones.","operationId":"create_from_template_api_spiritus_goals_from_template_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalFromTemplateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/goals":{"get":{"tags":["life-goals"],"summary":"List Goals","description":"List all goals split into active and completed, with milestones and linked habits.","operationId":"list_goals_api_spiritus_goals_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalListResponse"}}}}}},"post":{"tags":["life-goals"],"summary":"Create Goal","description":"Create a new custom life goal.","operationId":"create_goal_api_spiritus_goals_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalCreateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/goals/{goal_id}":{"patch":{"tags":["life-goals"],"summary":"Update Goal","description":"Update goal fields (title, description, deadline, sort_order).","operationId":"update_goal_api_spiritus_goals__goal_id__patch","parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"integer","title":"Goal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["life-goals"],"summary":"Delete Goal","description":"Delete a goal and cascade-delete its milestones and habit links.","operationId":"delete_goal_api_spiritus_goals__goal_id__delete","parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"integer","title":"Goal Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/goals/{goal_id}/complete":{"patch":{"tags":["life-goals"],"summary":"Toggle Goal Complete","description":"Toggle a goal's completed status.","operationId":"toggle_goal_complete_api_spiritus_goals__goal_id__complete_patch","parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"integer","title":"Goal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/goals/{goal_id}/progress":{"patch":{"tags":["life-goals"],"summary":"Update Goal Progress","description":"Set a goal's completion status explicitly.\n\nUnlike /complete (which toggles), this sets is_completed to the given\nvalue — idempotent-set semantics for external writers like theme\nwidgets (ThemeBridge's `goal_progress` write) that don't track prior\nstate. Backed by the same is_completed/completed_at fields /complete\nuses; the goal model has no separate progress field.","operationId":"update_goal_progress_api_spiritus_goals__goal_id__progress_patch","parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"integer","title":"Goal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalProgressRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/goals/{goal_id}/habits":{"post":{"tags":["life-goals"],"summary":"Link Habit","description":"Link a habit to a goal.","operationId":"link_habit_api_spiritus_goals__goal_id__habits_post","parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"integer","title":"Goal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HabitLinkRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/goals/{goal_id}/habits/{habit_id}":{"delete":{"tags":["life-goals"],"summary":"Unlink Habit","description":"Unlink a habit from a goal.","operationId":"unlink_habit_api_spiritus_goals__goal_id__habits__habit_id__delete","parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"integer","title":"Goal Id"}},{"name":"habit_id","in":"path","required":true,"schema":{"type":"integer","title":"Habit Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/goals/{goal_id}/milestones":{"post":{"tags":["life-goals"],"summary":"Create Milestone","description":"Add a milestone to a goal.","operationId":"create_milestone_api_spiritus_goals__goal_id__milestones_post","parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"integer","title":"Goal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MilestoneCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MilestoneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/goals/{goal_id}/milestones/{milestone_id}":{"patch":{"tags":["life-goals"],"summary":"Update Milestone","description":"Update or toggle a milestone.","operationId":"update_milestone_api_spiritus_goals__goal_id__milestones__milestone_id__patch","parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"integer","title":"Goal Id"}},{"name":"milestone_id","in":"path","required":true,"schema":{"type":"integer","title":"Milestone Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MilestoneUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MilestoneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["life-goals"],"summary":"Delete Milestone","description":"Delete a milestone.","operationId":"delete_milestone_api_spiritus_goals__goal_id__milestones__milestone_id__delete","parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"integer","title":"Goal Id"}},{"name":"milestone_id","in":"path","required":true,"schema":{"type":"integer","title":"Milestone Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/goals/{goal_id}/recommit":{"post":{"tags":["life-goals"],"summary":"Recommit Goal","description":"Recommit to a goal — push deadline forward after missing it.","operationId":"recommit_goal_api_spiritus_goals__goal_id__recommit_post","parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"integer","title":"Goal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommitRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/goals/{goal_id}/insight":{"post":{"tags":["life-goals"],"summary":"Goal Insight","description":"Generate an AI insight for a specific goal based on milestone and habit data.","operationId":"goal_insight_api_spiritus_goals__goal_id__insight_post","parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"integer","title":"Goal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/meditation/generate":{"post":{"tags":["life-meditation"],"summary":"Generate Meditation","description":"Start meditation generation in the background.\n\nReturns immediately with a session stub (status=\"generating\").\nThe client polls GET /sessions/{id} until status becomes \"ready\" or \"failed\".\nGeneration survives client disconnects and page refreshes.","operationId":"generate_meditation_api_spiritus_meditation_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateRequest"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/meditation/in-progress":{"get":{"tags":["life-meditation"],"summary":"Get In Progress","description":"Return the currently-generating session, if any. Used by frontend to\nresume polling after page refresh / navigation.\n\nAuto-fails sessions stuck generating for >10 minutes.","operationId":"get_in_progress_api_spiritus_meditation_in_progress_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/meditation/generate-script":{"post":{"tags":["life-meditation"],"summary":"Generate Script","description":"Generate a meditation script via the AI gateway (GPT-4o).\n\nUsed by the Chrome extension for the LLM step only.","operationId":"generate_script_api_spiritus_meditation_generate_script_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateScriptRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/meditation/generate-from-script":{"post":{"tags":["life-meditation"],"summary":"Generate From Script","description":"Take a pre-generated script and run TTS + stitching server-side.\n\nThe extension generates the script (expensive LLM call via proxy),\nthen hands it to the server for TTS + audio stitching (proven pipeline).\nReturns a complete session with audio, ready to play on any device.","operationId":"generate_from_script_api_spiritus_meditation_generate_from_script_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/meditation/upload":{"post":{"tags":["life-meditation"],"summary":"Upload Meditation","description":"Accept a meditation MP3 uploaded from the Chrome extension.\n\nCreates a MeditationSession record so the meditation appears across all\ndevices. The extension generates audio locally (via server-proxied API\ncalls) and uploads the finished file here for cross-device sync.","operationId":"upload_meditation_api_spiritus_meditation_upload_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_meditation_api_spiritus_meditation_upload_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/meditation/sessions":{"get":{"tags":["life-meditation"],"summary":"List Sessions","description":"List past meditation sessions (most recent first). Excludes in-progress.","operationId":"list_sessions_api_spiritus_meditation_sessions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionListResponse"}}}}}}},"/api/spiritus/meditation/sessions/{session_id}":{"get":{"tags":["life-meditation"],"summary":"Get Session Detail","description":"Get full session detail including transcript and audio URL.","operationId":"get_session_detail_api_spiritus_meditation_sessions__session_id__get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"integer","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["life-meditation"],"summary":"Delete Session","description":"Delete a meditation session and its audio file.","operationId":"delete_session_api_spiritus_meditation_sessions__session_id__delete","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"integer","title":"Session Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/meditation/sessions/{session_id}/favorite":{"patch":{"tags":["life-meditation"],"summary":"Toggle Favorite","description":"Toggle a session's favorite status.","operationId":"toggle_favorite_api_spiritus_meditation_sessions__session_id__favorite_patch","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"integer","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/meditation/sessions/{session_id}/mood":{"patch":{"tags":["life-meditation"],"summary":"Set Mood After","description":"Set the post-session mood emoji.","operationId":"set_mood_after_api_spiritus_meditation_sessions__session_id__mood_patch","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"integer","title":"Session Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoodAfterRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/meditation/sessions/{session_id}/complete":{"post":{"tags":["life-meditation"],"summary":"Complete Session","description":"Mark a meditation session as completed (user listened through).\n\nAwards XP and triggers challenge completion. Idempotent — calling\nagain on an already-completed session returns it without re-awarding.","operationId":"complete_session_api_spiritus_meditation_sessions__session_id__complete_post","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"integer","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/meditation/audio/{user_id}/{filename}":{"get":{"tags":["life-meditation"],"summary":"Serve Audio","description":"Serve a meditation audio file. Users can only access their own files.","operationId":"serve_audio_api_spiritus_meditation_audio__user_id___filename__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"filename","in":"path","required":true,"schema":{"type":"string","title":"Filename"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/meditation/remaining":{"get":{"tags":["life-meditation"],"summary":"Get Remaining","description":"Get how many meditation sessions remain today.","operationId":"get_remaining_api_spiritus_meditation_remaining_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemainingResponse"}}}}}}},"/api/spiritus/meditation/stats":{"get":{"tags":["life-meditation"],"summary":"Get Stats","description":"Get aggregate meditation stats — total sessions, total minutes, streak.","operationId":"get_stats_api_spiritus_meditation_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeditationStatsResponse"}}}}}}},"/api/spiritus/therapist/status":{"get":{"tags":["life-therapist"],"summary":"Therapist Status","description":"Get therapist availability: sessions used/remaining, first session flag.","operationId":"therapist_status_api_spiritus_therapist_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TherapistStatusResponse"}}}}}}},"/api/spiritus/therapist/greeting":{"get":{"tags":["life-therapist"],"summary":"Therapist Greeting","description":"Get a context-aware greeting for starting a new session.","operationId":"therapist_greeting_api_spiritus_therapist_greeting_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/therapist/starters":{"get":{"tags":["life-therapist"],"summary":"Conversation Starters","description":"Generate suggested conversation starters based on recent user data.","operationId":"conversation_starters_api_spiritus_therapist_starters_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TherapistStartersResponse"}}}}}}},"/api/spiritus/therapist/chat":{"post":{"tags":["life-therapist"],"summary":"Therapist Chat","description":"Send a message to the therapist and get a response.\n\nThe frontend maintains the full conversation in memory and sends\nthe growing message array with each request. Nothing is stored\nserver-side until end-session.","operationId":"therapist_chat_api_spiritus_therapist_chat_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TherapistChatRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TherapistChatResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/therapist/chat-stream":{"post":{"tags":["life-therapist"],"summary":"Therapist Chat Stream","description":"Streaming twin of /chat (SSE). Emits `{\"token\": str}` deltas as Venice\ngenerates, then one `{\"done\": true, ...}` event with the same metadata\n/chat returns. The buffered /chat endpoint is unchanged and remains the\nfallback + flag-off path.\n\nOrdering invariants (same as /chat): session/exchange caps and the crisis\nguardrail run BEFORE the LLM — a crisis message yields the scripted\nhotline response as a single token and Venice is never called.","operationId":"therapist_chat_stream_api_spiritus_therapist_chat_stream_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TherapistChatRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/therapist/end-session":{"post":{"tags":["life-therapist"],"summary":"End Session","description":"End a therapy session: generate a summary note from the conversation.\n\nThe full conversation is sent one final time for summarization,\nthen the client discards it. Only the structured note persists.","operationId":"end_session_api_spiritus_therapist_end_session_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TherapistEndSessionRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionNoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/therapist/notes":{"get":{"tags":["life-therapist"],"summary":"List Notes","description":"List all therapist session notes for the user, newest first.","operationId":"list_notes_api_spiritus_therapist_notes_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionNoteListResponse"}}}}}}},"/api/spiritus/therapist/notes/{note_id}":{"get":{"tags":["life-therapist"],"summary":"Get Note","description":"Get a single session note.","operationId":"get_note_api_spiritus_therapist_notes__note_id__get","parameters":[{"name":"note_id","in":"path","required":true,"schema":{"type":"integer","title":"Note Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionNoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["life-therapist"],"summary":"Update Note","description":"Update a session note (user can edit themes, patterns, follow-up).","operationId":"update_note_api_spiritus_therapist_notes__note_id__patch","parameters":[{"name":"note_id","in":"path","required":true,"schema":{"type":"integer","title":"Note Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionNoteUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionNoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["life-therapist"],"summary":"Delete Note","description":"Delete a session note.","operationId":"delete_note_api_spiritus_therapist_notes__note_id__delete","parameters":[{"name":"note_id","in":"path","required":true,"schema":{"type":"integer","title":"Note Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/therapist/speak":{"post":{"tags":["life-therapist"],"summary":"Therapist Speak","description":"Synthesize an assistant utterance via Cartesia, WITH word timestamps.\n\nReturns JSON `{audio, words, cost_usd, voice}` where `audio` is base64 MP3\nand `words` is [{word, start, end}] (seconds) so the avatar can lip-sync to\nthe real word onsets instead of guessing timing from the text. Budget:\npre-flight `can_spend`, post-success `record_spend`. Errors return 402\n(no credits), 503 (provider down), or 500 (unexpected).","operationId":"therapist_speak_api_spiritus_therapist_speak_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TherapistSpeakRequest"}}},"required":true},"responses":{"200":{"description":"JSON: base64 MP3 + word timestamps for lip-sync","content":{"application/json":{"schema":{}}}},"402":{"description":"Insufficient credits"},"503":{"description":"TTS provider unavailable"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/therapist/transcribe":{"post":{"tags":["life-therapist"],"summary":"Therapist Transcribe","description":"Transcribe a user audio recording via OpenAI Whisper.\n\nBudget: the pre-flight estimate uses file size (~1 MB ≈ 1 min for typical\nbrowser webm/opus). If the user has fewer ZugaTokens than the estimate,\nwe 402 before calling Whisper. The actual recorded spend uses Whisper's\nreported duration so users only pay for real audio length.","operationId":"therapist_transcribe_api_spiritus_therapist_transcribe_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_therapist_transcribe_api_spiritus_therapist_transcribe_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TherapistTranscribeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/settings":{"get":{"tags":["life-settings"],"summary":"Get Settings","description":"Return current user settings. Auto-creates defaults on first call.","operationId":"get_settings_api_spiritus_settings_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifeSettingsResponse"}}}}}},"put":{"tags":["life-settings"],"summary":"Update Settings","description":"Update user settings. Only provided fields are changed.","operationId":"update_settings_api_spiritus_settings_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifeSettingsUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LifeSettingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/onboarding":{"get":{"tags":["life-settings"],"summary":"Get Life Onboarding","description":"Check if the user has completed Spiritus studio onboarding.","operationId":"get_life_onboarding_api_spiritus_onboarding_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Life Onboarding Api Spiritus Onboarding Get"}}}}}}},"/api/spiritus/onboarding/complete":{"post":{"tags":["life-settings"],"summary":"Complete Life Onboarding","description":"Mark Spiritus studio onboarding as completed.","operationId":"complete_life_onboarding_api_spiritus_onboarding_complete_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Complete Life Onboarding Api Spiritus Onboarding Complete Post"}}}}}}},"/api/spiritus/onboarding/reset":{"post":{"tags":["life-settings"],"summary":"Reset Life Onboarding","description":"Reset Spiritus studio onboarding so the user can replay it.","operationId":"reset_life_onboarding_api_spiritus_onboarding_reset_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Reset Life Onboarding Api Spiritus Onboarding Reset Post"}}}}}}},"/api/spiritus/breath/today":{"get":{"tags":["life-settings"],"summary":"Get Breath Today","description":"Return whether the user has completed today's breath ritual on any device.\n\n\"Today\" is in the user's configured timezone — so rollover happens at the\nuser's midnight, not UTC's. Otherwise the prompt re-appears at 8pm EDT\n(UTC midnight) instead of true local midnight.","operationId":"get_breath_today_api_spiritus_breath_today_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Breath Today Api Spiritus Breath Today Get"}}}}}}},"/api/spiritus/breath/done":{"post":{"tags":["life-settings"],"summary":"Mark Breath Done","description":"Mark today's breath ritual complete. Idempotent — safe to call repeatedly.","operationId":"mark_breath_done_api_spiritus_breath_done_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Mark Breath Done Api Spiritus Breath Done Post"}}}}}}},"/api/spiritus/settings/personalization":{"get":{"tags":["life-settings"],"summary":"Get Personalization","description":"Get current personalization config (readable by frontend and Zugabot).","operationId":"get_personalization_api_spiritus_settings_personalization_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalizationResponse"}}}}}},"patch":{"tags":["life-settings"],"summary":"Update Personalization","description":"Update personalization config. Writable by both the user and Zugabot agent.\n\nZugabot can learn which gamification style works for each user (Bartle player types)\nand adjust challenge difficulty in real-time (Csikszentmihalyi's flow channel).","operationId":"update_personalization_api_spiritus_settings_personalization_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalizationUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalizationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/internal/apply-theme":{"post":{"tags":["life-settings"],"summary":"Internal Apply Theme","description":"Service-to-service endpoint for Zugabot to apply themes.\n\nNow forwards to ZugaApp's theme override system instead of writing\nto custom_colors. This ensures themes show in Settings > My Themes\nand can be scoped to any studio.","operationId":"internal_apply_theme_api_spiritus_internal_apply_theme_post","parameters":[{"name":"X-Service-Key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Service-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalThemeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/personality/items":{"get":{"tags":["spiritus-personality"],"summary":"Get Items","description":"Combined item bank: 32 OEJTS bipolar items + 4 Neuroticism Likert items.\nKeying (scale/sign/reverse) is never exposed.","operationId":"get_items_api_spiritus_personality_items_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemBankResponse"}}}}}}},"/api/spiritus/personality":{"get":{"tags":["spiritus-personality"],"summary":"Get Personality","description":"Return the caller's stored personality result, or {completed: false}.","operationId":"get_personality_api_spiritus_personality_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalityResponse"}}}}}},"delete":{"tags":["spiritus-personality"],"summary":"Delete Personality","description":"Revoke consent and purge the caller's personality row.","operationId":"delete_personality_api_spiritus_personality_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Delete Personality Api Spiritus Personality Delete"}}}}}}},"/api/spiritus/personality/submit":{"post":{"tags":["spiritus-personality"],"summary":"Submit Personality","description":"Score the combined assessment and store the 16-type + Big-Five result. Requires explicit consent.","operationId":"submit_personality_api_spiritus_personality_submit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonalityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/personality/share":{"get":{"tags":["spiritus-personality"],"summary":"Get Share Status","description":"Whether the caller is sharing a coarse Big-Five vector with Zugabot.","operationId":"get_share_status_api_spiritus_personality_share_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareStatus"}}}}}},"patch":{"tags":["spiritus-personality"],"summary":"Update Share","description":"Toggle the coarse-vector crossing opt-in. Off by default; off clears it.","operationId":"update_share_api_spiritus_personality_share_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/internal/personality/{user_id}":{"get":{"tags":["spiritus-personality-internal"],"summary":"Internal Get Coarse Vector","description":"Zugabot reads a user's COARSE Big-Five vector + 4-letter type — only if they opted\ninto sharing. Returns 404 (not 403) when not shared so a non-sharing user is\nindistinguishable from one who never took the test. Never exposes raw answers\nor exact floats.","operationId":"internal_get_coarse_vector_api_spiritus_internal_personality__user_id__get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"X-Service-Key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Service-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoarseVector"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/mood/forecast":{"get":{"tags":["life-forecasting"],"summary":"Get Mood Forecast","description":"Compute mood analytics: trend, patterns, forecast, correlations.\n\nPure statistics — no AI calls, no stored predictions.\nMinimum 7-day window to produce meaningful results.","operationId":"get_mood_forecast_api_spiritus_mood_forecast_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":7,"description":"Analysis window in days","default":30,"title":"Days"},"description":"Analysis window in days"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoodForecastResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/forecasting/narrative":{"get":{"tags":["life-forecasting"],"summary":"Get Weekly Narrative","description":"AI-generated weekly narrative synthesis — mood trends, habit patterns, goal progress.\n\nCached: one generation per user per week (Monday-Sunday).\nThe #1 gap in mood tracking research is lack of interpretation — this fills it.","operationId":"get_weekly_narrative_api_spiritus_forecasting_narrative_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/mood/forecast/arima":{"get":{"tags":["life-forecasting"],"summary":"Get Arima Forecast","description":"ARIMA-based mood forecast — next day and 7-day prediction.\n\nUses ARIMA(1,1,1) on daily average valence scores.\nRequires at least 7 mood entries across 7 different days.","operationId":"get_arima_forecast_api_spiritus_mood_forecast_arima_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":7,"description":"Analysis window in days","default":30,"title":"Days"},"description":"Analysis window in days"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArimaForecastResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/mood/forecast/arimax":{"get":{"tags":["life-forecasting"],"summary":"Get Arimax Forecast","description":"ARIMAX multivariate mood forecast — mood + external factors.\n\nUses ARIMA(1,1,1) with exogenous variables: habit completions,\nmeditation sessions, and journal entries. Falls back to plain\nARIMA if no external factor data has variance.","operationId":"get_arimax_forecast_api_spiritus_mood_forecast_arimax_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":7,"description":"Analysis window in days","default":30,"title":"Days"},"description":"Analysis window in days"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArimaxForecastResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/gamification":{"get":{"tags":["life-gamification"],"summary":"Get Gamification Dashboard","description":"Full gamification status — XP, badges, recent transactions, and today's challenges.","operationId":"get_gamification_dashboard_api_spiritus_gamification_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GamificationDashboard"}}}}}}},"/api/spiritus/gamification/insights":{"get":{"tags":["life-gamification"],"summary":"Get Insights","description":"Get contextual psychological insight cards triggered by user activity.","operationId":"get_insights_api_spiritus_gamification_insights_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/gamification/insights/{insight_key}/dismiss":{"post":{"tags":["life-gamification"],"summary":"Dismiss Insight","description":"Dismiss an insight card so it won't show again.","operationId":"dismiss_insight_api_spiritus_gamification_insights__insight_key__dismiss_post","parameters":[{"name":"insight_key","in":"path","required":true,"schema":{"type":"string","title":"Insight Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/gamification/xp":{"get":{"tags":["life-gamification"],"summary":"Get Xp Status","description":"Current XP, level, streak, and progress toward next level.","operationId":"get_xp_status_api_spiritus_gamification_xp_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/XPStatusResponse"}}}}}}},"/api/spiritus/gamification/badges":{"get":{"tags":["life-gamification"],"summary":"Get Badges","description":"All badges earned by this user, enriched with badge metadata.","operationId":"get_badges_api_spiritus_gamification_badges_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BadgeResponse"},"type":"array","title":"Response Get Badges Api Spiritus Gamification Badges Get"}}}}}}},"/api/spiritus/gamification/challenges":{"get":{"tags":["life-gamification"],"summary":"Get Daily Challenges","description":"Today's daily challenges for this user (AI-generated on first request, static fallback).","operationId":"get_daily_challenges_api_spiritus_gamification_challenges_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/DailyChallengeResponse"},"type":"array","title":"Response Get Daily Challenges Api Spiritus Gamification Challenges Get"}}}}}}},"/api/spiritus/gamification/weekly-quests":{"get":{"tags":["life-gamification"],"summary":"Get Weekly Quests","description":"This week's quests for this user (AI-generated on first request).","operationId":"get_weekly_quests_api_spiritus_gamification_weekly_quests_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/WeeklyQuestResponse"},"type":"array","title":"Response Get Weekly Quests Api Spiritus Gamification Weekly Quests Get"}}}}}}},"/api/spiritus/gamification/award":{"post":{"tags":["life-gamification"],"summary":"Award Xp","description":"Award XP to the authenticated user.\n\nThis endpoint is intended for internal calls from other Spiritus modules\nand for testing.  The source must be a known XP_TABLE key or 'streak_bonus'.\n\nValid sources: mood_log, habit_check, journal_entry, meditation_complete,\ntherapist_session, goal_milestone, daily_challenge, streak_bonus.","operationId":"award_xp_api_spiritus_gamification_award_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwardXPRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/XPGainResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/gamification/prestige":{"post":{"tags":["life-gamification"],"summary":"Prestige","description":"Prestige: reset level/XP to 1, gain permanent XP multiplier and unique badge.\n\nRequires reaching the prestige level (25). Streaks and badges are kept.","operationId":"prestige_api_spiritus_gamification_prestige_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrestigeResponse"}}}}}}},"/api/spiritus/notifications/vapid-key":{"get":{"tags":["life-notifications"],"summary":"Get Vapid Key","description":"Return the VAPID public key for frontend push subscription.","operationId":"get_vapid_key_api_spiritus_notifications_vapid_key_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/notifications/subscribe":{"post":{"tags":["life-notifications"],"summary":"Subscribe","description":"Register a push subscription for the authenticated user.","operationId":"subscribe_api_spiritus_notifications_subscribe_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/notifications/unsubscribe":{"delete":{"tags":["life-notifications"],"summary":"Unsubscribe","description":"Deactivate all push subscriptions for the authenticated user.","operationId":"unsubscribe_api_spiritus_notifications_unsubscribe_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/notifications/preferences":{"get":{"tags":["life-notifications"],"summary":"Get Preferences","description":"Get notification preferences for the authenticated user.","operationId":"get_preferences_api_spiritus_notifications_preferences_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferencesResponse"}}}}}},"put":{"tags":["life-notifications"],"summary":"Update Preferences","description":"Update notification preferences for the authenticated user.","operationId":"update_preferences_api_spiritus_notifications_preferences_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferencesRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreferencesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/notifications/trigger-check":{"post":{"tags":["life-notifications"],"summary":"Trigger Notification Check","description":"Manually trigger the notification scheduler check.\n\nIntended for daemon/cron or admin testing.","operationId":"trigger_notification_check_api_spiritus_notifications_trigger_check_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/discover/today":{"get":{"tags":["spiritus-discover"],"summary":"Get Today","operationId":"get_today_api_spiritus_discover_today_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodayResponse"}}}}}}},"/api/spiritus/discover/feed":{"get":{"tags":["spiritus-discover"],"summary":"Get Feed","operationId":"get_feed_api_spiritus_discover_feed_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Cursor"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/discover/search":{"get":{"tags":["spiritus-discover"],"summary":"Search","operationId":"search_api_spiritus_discover_search_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","default":"","title":"Q"}},{"name":"school","in":"query","required":false,"schema":{"type":"string","default":"","title":"School"}},{"name":"kind","in":"query","required":false,"schema":{"type":"string","default":"","title":"Kind"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/discover/thinker/{thinker_key}":{"get":{"tags":["spiritus-discover"],"summary":"Thinker Profile","operationId":"thinker_profile_api_spiritus_discover_thinker__thinker_key__get","parameters":[{"name":"thinker_key","in":"path","required":true,"schema":{"type":"string","title":"Thinker Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/discover/sources":{"get":{"tags":["spiritus-discover"],"summary":"List Sources","description":"All sources with how many active ideas each has (grouped 'by book' view).","operationId":"list_sources_api_spiritus_discover_sources_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourcesResponse"}}}}}}},"/api/spiritus/discover/source/{source_key}":{"get":{"tags":["spiritus-discover"],"summary":"Source Detail","description":"One source + all of its active cards (the source detail / reader view).","operationId":"source_detail_api_spiritus_discover_source__source_key__get","parameters":[{"name":"source_key","in":"path","required":true,"schema":{"type":"string","title":"Source Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/discover/{card_id}/react":{"post":{"tags":["spiritus-discover"],"summary":"React","operationId":"react_api_spiritus_discover__card_id__react_post","parameters":[{"name":"card_id","in":"path","required":true,"schema":{"type":"integer","title":"Card Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReactRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/discover/stash":{"get":{"tags":["spiritus-discover"],"summary":"Get Stash","operationId":"get_stash_api_spiritus_discover_stash_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StashResponse"}}}}}}},"/api/spiritus/discover/collections":{"get":{"tags":["spiritus-discover"],"summary":"List Collections","operationId":"list_collections_api_spiritus_discover_collections_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionsResponse"}}}}}},"post":{"tags":["spiritus-discover"],"summary":"Create Collection","operationId":"create_collection_api_spiritus_discover_collections_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/discover/stash/{card_id}/collection":{"post":{"tags":["spiritus-discover"],"summary":"Assign Collection","operationId":"assign_collection_api_spiritus_discover_stash__card_id__collection_post","parameters":[{"name":"card_id","in":"path","required":true,"schema":{"type":"integer","title":"Card Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/data/reset/mood":{"delete":{"tags":["life-data-management"],"summary":"Reset Mood","description":"Delete all mood entries for this user.","operationId":"reset_mood_api_spiritus_data_reset_mood_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/data/reset/habits":{"delete":{"tags":["life-data-management"],"summary":"Reset Habits","description":"Delete all habit logs, insights, and definitions for this user.\n\nThis is a full wipe — custom habits are removed along with all history.\nPreset habits will be re-seeded automatically on the next visit to the\nhabits page.","operationId":"reset_habits_api_spiritus_data_reset_habits_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/data/reset/goals":{"delete":{"tags":["life-data-management"],"summary":"Reset Goals","description":"Delete all goal definitions for this user.\n\nMilestones and habit links are removed automatically via FK cascade delete.","operationId":"reset_goals_api_spiritus_data_reset_goals_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/data/reset/journal":{"delete":{"tags":["life-data-management"],"summary":"Reset Journal","description":"Delete all journal entries for this user.\n\nReflections are removed automatically via FK cascade delete.","operationId":"reset_journal_api_spiritus_data_reset_journal_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/data/reset/meditation":{"delete":{"tags":["life-data-management"],"summary":"Reset Meditation","description":"Delete all meditation sessions for this user and remove their audio files.\n\nAudio files live at data/meditation_audio/{user_id}/. The entire directory\nis removed with shutil.rmtree. The path is constructed server-side from\nuser.id — no user input touches the filesystem path.","operationId":"reset_meditation_api_spiritus_data_reset_meditation_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/data/reset/breathing":{"delete":{"tags":["life-data-management"],"summary":"Reset Breathing","description":"Reset the daily breath cold-open gate for this user.\n\nThere is no breath history table — the gate is a single date field\n(last_breath_date) on the user's settings row. Nulling it makes today's\nbreathing ritual eligible to be offered again. Settings preferences are\nuntouched; only the daily-state field is cleared. Returns 0 if the user\nhas no settings row yet (nothing to reset).","operationId":"reset_breathing_api_spiritus_data_reset_breathing_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/data/reset/therapist":{"delete":{"tags":["life-data-management"],"summary":"Reset Therapist","description":"Delete all therapist session notes for this user.","operationId":"reset_therapist_api_spiritus_data_reset_therapist_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/data/reset/gamification":{"delete":{"tags":["life-data-management"],"summary":"Reset Gamification","description":"Delete all gamification data (XP, transactions, badges, challenges) for this user.","operationId":"reset_gamification_api_spiritus_data_reset_gamification_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/data/reset/all":{"delete":{"tags":["life-data-management"],"summary":"Reset All","description":"Delete all Spiritus data for this user across every module.\n\nSettings are intentionally preserved — the user keeps their timezone,\ntheme, voice, and ambience preferences after a data reset.\n\nReturns per-module deleted counts plus a combined total.","operationId":"reset_all_api_spiritus_data_reset_all_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/consent":{"get":{"tags":["life-consent"],"summary":"Get Consent","operationId":"get_consent_api_spiritus_consent_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentState"}}}}}},"post":{"tags":["life-consent"],"summary":"Record Consent","description":"Stamp consent timestamps. Idempotent: re-posting only stamps fields that\nhaven't been stamped yet — consent can be GIVEN but never silently revoked\nthrough this endpoint. (Per-flag revocation uses dedicated revoke endpoints,\ne.g. POST /api/spiritus/consent/zugabot/revoke; full account deletion runs\nthrough DELETE /api/spiritus/users/me.)","operationId":"record_consent_api_spiritus_consent_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentState"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/consent/zugabot/revoke":{"post":{"tags":["life-consent"],"summary":"Revoke Zugabot Connection","description":"Revoke the Zugabot feed: clear the consent stamp, then REQUEST hard-deletion of the already-ingested Spiritus slice (actioned by Zugabot's purge consumer). Idempotent.\n\nConsent is the user-facing source of truth: we clear (and commit) the stamp\nfirst so the export endpoint 403s immediately. The purge runs after; if it\nfails we still return success (consent IS off) and rely on the durable purge\nretry (Task B8) — we never leave consent ON because the purge failed.","operationId":"revoke_zugabot_connection_api_spiritus_consent_zugabot_revoke_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentState"}}}}}}},"/api/spiritus/users/me":{"delete":{"tags":["life-users"],"summary":"Delete Me","description":"Full Spiritus account deletion.\n\nRuns the same per-module purge as /api/spiritus/data/reset/all and stamps\ndeletion_requested_at on the user's consent record. The stamp is the\nSLA anchor — any latent caches / logs / backups must be purged within\n30 days of that timestamp.","operationId":"delete_me_api_spiritus_users_me_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponse"}}}}}}},"/api/spiritus/zugabot-export":{"get":{"tags":["spiritus-zugabot"],"summary":"Zugabot Export","operationId":"zugabot_export_api_spiritus_zugabot_export_get","parameters":[{"name":"x-service-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/zugabot-outbox":{"get":{"tags":["spiritus-zugabot"],"summary":"Zugabot Outbox Drain","description":"Zugabot drains pending events. Service-key gated (server-to-server; no user\ntoken). For each pending pull_signal we inline the derived slice ONLY if the\nuser STILL consents (re-checked here) — a user who revoked between signal and\ndrain leaks nothing. Purge events carry just the user_id.","operationId":"zugabot_outbox_drain_api_spiritus_zugabot_outbox_get","parameters":[{"name":"x-service-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/zugabot-outbox/ack":{"post":{"tags":["spiritus-zugabot"],"summary":"Zugabot Outbox Ack","description":"Mark drained events consumed. Service-key gated.","operationId":"zugabot_outbox_ack_api_spiritus_zugabot_outbox_ack_post","parameters":[{"name":"x-service-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Service-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_zugabot_outbox_ack_api_spiritus_zugabot_outbox_ack_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/spiritus/dashboard":{"get":{"tags":["life-dashboard"],"summary":"Get Dashboard","description":"Aggregated dashboard data — one call, all modules.","operationId":"get_dashboard_api_spiritus_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/spiritus/commands":{"get":{"tags":["life-zugaos"],"summary":"Get Commands","description":"Return Spiritus's intent catalog. Public — capability descriptors only,\nno user data. ZugaOS aggregator merges this with other studios' catalogs.","operationId":"get_commands_api_spiritus_commands_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Commands Api Spiritus Commands Get"}}}}}}}},"components":{"schemas":{"AdminDeleteUserRequest":{"properties":{"email":{"type":"string","title":"Email"},"confirm":{"type":"string","title":"Confirm"}},"type":"object","required":["email","confirm"],"title":"AdminDeleteUserRequest"},"AdminResetRequest":{"properties":{"email":{"type":"string","title":"Email"}},"type":"object","required":["email"],"title":"AdminResetRequest"},"AllStreaksResponse":{"properties":{"habits":{"items":{"$ref":"#/components/schemas/HabitStreakInfo"},"type":"array","title":"Habits"},"overall_current":{"type":"integer","title":"Overall Current"},"overall_longest":{"type":"integer","title":"Overall Longest"}},"type":"object","required":["habits","overall_current","overall_longest"],"title":"AllStreaksResponse"},"AmbienceType":{"type":"string","enum":["rain","ocean","forest","bowls","silence"],"title":"AmbienceType"},"Archetype":{"properties":{"code":{"type":"string","title":"Code"},"name":{"type":"string","title":"Name"},"tagline":{"type":"string","title":"Tagline"},"blurb":{"type":"string","title":"Blurb"},"strengths":{"items":{"type":"string"},"type":"array","title":"Strengths"},"growth":{"items":{"type":"string"},"type":"array","title":"Growth"}},"type":"object","required":["code","name","tagline","blurb","strengths","growth"],"title":"Archetype"},"ArimaDayForecast":{"properties":{"date":{"type":"string","title":"Date"},"forecast_valence":{"type":"number","title":"Forecast Valence"},"forecast_label":{"type":"string","title":"Forecast Label"}},"type":"object","required":["date","forecast_valence","forecast_label"],"title":"ArimaDayForecast"},"ArimaForecastResponse":{"properties":{"next_day":{"anyOf":[{"$ref":"#/components/schemas/ArimaDayForecast"},{"type":"null"}]},"next_7_days":{"items":{"$ref":"#/components/schemas/ArimaWeekEntry"},"type":"array","title":"Next 7 Days"},"confidence":{"type":"string","title":"Confidence"},"data_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Data Days"},"model_order":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Model Order"},"aic":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Aic"},"stationarity":{"anyOf":[{"$ref":"#/components/schemas/StationarityResult"},{"type":"null"}]},"description":{"type":"string","title":"Description"},"method":{"type":"string","title":"Method","default":"arima"}},"type":"object","required":["next_day","next_7_days","confidence","description"],"title":"ArimaForecastResponse"},"ArimaWeekEntry":{"properties":{"date":{"type":"string","title":"Date"},"day":{"type":"string","title":"Day"},"forecast_valence":{"type":"number","title":"Forecast Valence"},"forecast_label":{"type":"string","title":"Forecast Label"}},"type":"object","required":["date","day","forecast_valence","forecast_label"],"title":"ArimaWeekEntry"},"ArimaxForecastResponse":{"properties":{"next_day":{"anyOf":[{"$ref":"#/components/schemas/ArimaDayForecast"},{"type":"null"}]},"next_7_days":{"items":{"$ref":"#/components/schemas/ArimaWeekEntry"},"type":"array","title":"Next 7 Days"},"confidence":{"type":"string","title":"Confidence"},"data_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Data Days"},"model_order":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Model Order"},"aic":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Aic"},"exogenous_factors":{"items":{"type":"string"},"type":"array","title":"Exogenous Factors","default":[]},"description":{"type":"string","title":"Description"},"method":{"type":"string","title":"Method","default":"arimax"}},"type":"object","required":["next_day","next_7_days","confidence","description"],"title":"ArimaxForecastResponse"},"AssignRequest":{"properties":{"collection_id":{"type":"integer","title":"Collection Id"}},"type":"object","required":["collection_id"],"title":"AssignRequest"},"AuthConfigResponse":{"properties":{"auth_mode":{"type":"string","title":"Auth Mode"},"google_client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Google Client Id"},"github_client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Github Client Id"},"microsoft_client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Microsoft Client Id"},"providers":{"items":{"type":"string"},"type":"array","title":"Providers","default":[]}},"type":"object","required":["auth_mode"],"title":"AuthConfigResponse"},"AwardXPRequest":{"properties":{"source":{"type":"string","title":"Source"},"description":{"type":"string","title":"Description"},"base_amount":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Base Amount"}},"type":"object","required":["source","description"],"title":"AwardXPRequest"},"AxisVector":{"properties":{"IE":{"type":"integer","title":"Ie"},"SN":{"type":"integer","title":"Sn"},"FT":{"type":"integer","title":"Ft"},"JP":{"type":"integer","title":"Jp"}},"type":"object","required":["IE","SN","FT","JP"],"title":"AxisVector"},"BadgeResponse":{"properties":{"badge_key":{"type":"string","title":"Badge Key"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"emoji":{"type":"string","title":"Emoji"},"earned_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Earned At"}},"type":"object","required":["badge_key","title","description","emoji"],"title":"BadgeResponse"},"BgThemePrefBody":{"properties":{"theme":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Theme"}},"type":"object","title":"BgThemePrefBody"},"Big5Vector":{"properties":{"O":{"type":"number","title":"O"},"C":{"type":"number","title":"C"},"E":{"type":"number","title":"E"},"A":{"type":"number","title":"A"},"N":{"type":"number","title":"N"}},"type":"object","required":["O","C","E","A","N"],"title":"Big5Vector"},"Body_therapist_transcribe_api_spiritus_therapist_transcribe_post":{"properties":{"audio":{"type":"string","contentMediaType":"application/octet-stream","title":"Audio"}},"type":"object","required":["audio"],"title":"Body_therapist_transcribe_api_spiritus_therapist_transcribe_post"},"Body_upload_meditation_api_spiritus_meditation_upload_post":{"properties":{"audio":{"type":"string","contentMediaType":"application/octet-stream","title":"Audio"},"title":{"type":"string","title":"Title"},"transcript":{"type":"string","title":"Transcript"},"type":{"type":"string","title":"Type"},"length":{"type":"string","title":"Length","default":"medium"},"ambience":{"type":"string","title":"Ambience","default":"silence"},"voice":{"type":"string","title":"Voice","default":"serene"},"focus":{"type":"string","title":"Focus","default":""},"model_used":{"type":"string","title":"Model Used","default":""},"tts_model":{"type":"string","title":"Tts Model","default":"tts-1-hd"},"cost":{"type":"number","title":"Cost","default":0.0},"duration_seconds":{"type":"integer","title":"Duration Seconds","default":0}},"type":"object","required":["audio","title","transcript","type"],"title":"Body_upload_meditation_api_spiritus_meditation_upload_post"},"Body_zugabot_outbox_ack_api_spiritus_zugabot_outbox_ack_post":{"properties":{"ids":{"items":{"type":"integer"},"type":"array","title":"Ids"}},"type":"object","required":["ids"],"title":"Body_zugabot_outbox_ack_api_spiritus_zugabot_outbox_ack_post"},"CardOut":{"properties":{"id":{"type":"integer","title":"Id"},"kind":{"type":"string","title":"Kind"},"title":{"type":"string","title":"Title"},"body":{"type":"string","title":"Body"},"attribution":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attribution"},"source_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Ref"},"school_tag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"School Tag"},"reflect_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reflect Prompt"},"source":{"anyOf":[{"$ref":"#/components/schemas/SourceOut"},{"type":"null"}]},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["id","kind","title","body"],"title":"CardOut"},"ChangePasswordRequest":{"properties":{"current_password":{"type":"string","title":"Current Password"},"new_password":{"type":"string","title":"New Password"}},"type":"object","required":["current_password","new_password"],"title":"ChangePasswordRequest"},"CoarseVector":{"properties":{"O":{"type":"string","title":"O"},"C":{"type":"string","title":"C"},"E":{"type":"string","title":"E"},"A":{"type":"string","title":"A"},"N":{"type":"string","title":"N"},"type_code":{"type":"string","title":"Type Code"}},"type":"object","required":["O","C","E","A","N","type_code"],"title":"CoarseVector"},"CollectionOut":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"CollectionOut"},"CollectionsResponse":{"properties":{"collections":{"items":{"$ref":"#/components/schemas/CollectionOut"},"type":"array","title":"Collections"}},"type":"object","required":["collections"],"title":"CollectionsResponse"},"ConsentBody":{"properties":{"health_collected":{"type":"boolean","title":"Health Collected","default":false},"ai_sharing":{"type":"boolean","title":"Ai Sharing","default":false},"age_confirmed":{"type":"boolean","title":"Age Confirmed","default":false},"zugabot_connection":{"type":"boolean","title":"Zugabot Connection","default":false}},"type":"object","title":"ConsentBody"},"ConsentState":{"properties":{"health_collected_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Health Collected At"},"ai_sharing_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Ai Sharing At"},"age_confirmed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Age Confirmed At"},"deletion_requested_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deletion Requested At"},"zugabot_connection_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Zugabot Connection At"},"consent_version":{"type":"integer","title":"Consent Version","default":0},"current_version":{"type":"integer","title":"Current Version","default":0}},"type":"object","required":["health_collected_at","ai_sharing_at","age_confirmed_at","deletion_requested_at"],"title":"ConsentState"},"ConversationStarter":{"properties":{"text":{"type":"string","title":"Text"},"source":{"type":"string","title":"Source"}},"type":"object","required":["text","source"],"title":"ConversationStarter"},"CreateCollectionRequest":{"properties":{"name":{"type":"string","title":"Name"}},"type":"object","required":["name"],"title":"CreateCollectionRequest"},"DailyChallengeResponse":{"properties":{"challenge_key":{"type":"string","title":"Challenge Key"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"xp_reward":{"type":"integer","title":"Xp Reward"},"is_completed":{"type":"boolean","title":"Is Completed"},"is_ai_generated":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Ai Generated","default":false},"goal_connection":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Goal Connection"}},"type":"object","required":["challenge_key","title","description","xp_reward","is_completed"],"title":"DailyChallengeResponse"},"DailyCheckInResponse":{"properties":{"date":{"type":"string","format":"date","title":"Date"},"habits":{"items":{"$ref":"#/components/schemas/HabitCheckInItem"},"type":"array","title":"Habits"},"completed_count":{"type":"integer","title":"Completed Count"},"total_count":{"type":"integer","title":"Total Count"}},"type":"object","required":["date","habits","completed_count","total_count"],"title":"DailyCheckInResponse"},"DayHistory":{"properties":{"date":{"type":"string","format":"date","title":"Date"},"completed_count":{"type":"integer","title":"Completed Count"},"total_active":{"type":"integer","title":"Total Active"},"completion_rate":{"type":"number","title":"Completion Rate"},"habits_done":{"items":{"type":"string"},"type":"array","title":"Habits Done"}},"type":"object","required":["date","completed_count","total_active","completion_rate","habits_done"],"title":"DayHistory"},"DayOfWeekEntry":{"properties":{"day":{"type":"string","title":"Day"},"avg_valence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Valence"},"entries":{"type":"integer","title":"Entries"}},"type":"object","required":["day","avg_valence","entries"],"title":"DayOfWeekEntry"},"DayOfWeekResult":{"properties":{"days":{"items":{"$ref":"#/components/schemas/DayOfWeekEntry"},"type":"array","title":"Days"},"description":{"type":"string","title":"Description"}},"type":"object","required":["days","description"],"title":"DayOfWeekResult"},"DeleteResponse":{"properties":{"status":{"type":"string","title":"Status"},"deletion_requested_at":{"type":"string","format":"date-time","title":"Deletion Requested At"},"sla_days":{"type":"integer","title":"Sla Days"},"purged":{"additionalProperties":true,"type":"object","title":"Purged"}},"type":"object","required":["status","deletion_requested_at","sla_days","purged"],"title":"DeleteResponse"},"FeedResponse":{"properties":{"cards":{"items":{"$ref":"#/components/schemas/CardOut"},"type":"array","title":"Cards"},"next_cursor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Cursor"}},"type":"object","required":["cards"],"title":"FeedResponse"},"ForecastResult":{"properties":{"forecast_valence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Forecast Valence"},"forecast_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Forecast Label"},"confidence":{"type":"string","title":"Confidence"},"method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method"},"description":{"type":"string","title":"Description"}},"type":"object","required":["forecast_valence","forecast_label","confidence","description"],"title":"ForecastResult"},"ForgotPasswordRequest":{"properties":{"email":{"type":"string","title":"Email"}},"type":"object","required":["email"],"title":"ForgotPasswordRequest"},"GamificationDashboard":{"properties":{"xp":{"$ref":"#/components/schemas/XPStatusResponse"},"badges":{"items":{"$ref":"#/components/schemas/BadgeResponse"},"type":"array","title":"Badges"},"recent_xp":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Recent Xp"},"daily_challenges":{"items":{"$ref":"#/components/schemas/DailyChallengeResponse"},"type":"array","title":"Daily Challenges"},"weekly_quests":{"items":{"$ref":"#/components/schemas/WeeklyQuestResponse"},"type":"array","title":"Weekly Quests"}},"type":"object","required":["xp","badges","recent_xp","daily_challenges","weekly_quests"],"title":"GamificationDashboard"},"GenerateRequest":{"properties":{"type":{"$ref":"#/components/schemas/MeditationType"},"length":{"$ref":"#/components/schemas/MeditationLength","default":"medium"},"ambience":{"$ref":"#/components/schemas/AmbienceType","default":"rain"},"voice":{"$ref":"#/components/schemas/VoiceType","default":"serene"},"focus":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Focus"}},"type":"object","required":["type"],"title":"GenerateRequest"},"GenerateScriptRequest":{"properties":{"prompt":{"type":"string","title":"Prompt"},"max_tokens":{"type":"integer","title":"Max Tokens","default":3000},"task":{"type":"string","title":"Task","default":"creative"}},"type":"object","required":["prompt"],"title":"GenerateScriptRequest"},"GoalCreateRequest":{"properties":{"title":{"type":"string","maxLength":200,"minLength":1,"title":"Title"},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Description"},"deadline":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Deadline"},"identity_statement":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Identity Statement"},"obstacle":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Obstacle"},"implementation_plan":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Implementation Plan"},"approach_reframe":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Approach Reframe"}},"type":"object","required":["title"],"title":"GoalCreateRequest"},"GoalFromTemplateRequest":{"properties":{"template_key":{"type":"string","maxLength":50,"minLength":1,"title":"Template Key"}},"type":"object","required":["template_key"],"title":"GoalFromTemplateRequest"},"GoalListResponse":{"properties":{"active":{"items":{"$ref":"#/components/schemas/GoalResponse"},"type":"array","title":"Active"},"completed":{"items":{"$ref":"#/components/schemas/GoalResponse"},"type":"array","title":"Completed"}},"type":"object","required":["active","completed"],"title":"GoalListResponse"},"GoalProgressRequest":{"properties":{"is_completed":{"type":"boolean","title":"Is Completed"}},"type":"object","required":["is_completed"],"title":"GoalProgressRequest"},"GoalResponse":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"deadline":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Deadline"},"is_completed":{"type":"boolean","title":"Is Completed"},"sort_order":{"type":"integer","title":"Sort Order"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"template_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Template Key"},"identity_statement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Identity Statement"},"obstacle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Obstacle"},"implementation_plan":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Implementation Plan"},"approach_reframe":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Approach Reframe"},"milestones":{"items":{"$ref":"#/components/schemas/MilestoneResponse"},"type":"array","title":"Milestones"},"milestone_count":{"type":"integer","title":"Milestone Count","default":0},"milestone_done":{"type":"integer","title":"Milestone Done","default":0},"linked_habits":{"items":{"$ref":"#/components/schemas/LinkedHabitResponse"},"type":"array","title":"Linked Habits","default":[]}},"type":"object","required":["id","title","description","deadline","is_completed","sort_order","completed_at","created_at","updated_at","milestones"],"title":"GoalResponse"},"GoalTemplateResponse":{"properties":{"key":{"type":"string","title":"Key"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"suggested_habits":{"items":{"type":"string"},"type":"array","title":"Suggested Habits"},"already_adopted":{"type":"boolean","title":"Already Adopted","default":false}},"type":"object","required":["key","title","description","suggested_habits"],"title":"GoalTemplateResponse"},"GoalUpdateRequest":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Description"},"deadline":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Deadline"},"sort_order":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Sort Order"},"identity_statement":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Identity Statement"},"obstacle":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Obstacle"},"implementation_plan":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Implementation Plan"},"approach_reframe":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Approach Reframe"}},"type":"object","title":"GoalUpdateRequest"},"GoogleLoginRequest":{"properties":{"credential":{"type":"string","title":"Credential"}},"type":"object","required":["credential"],"title":"GoogleLoginRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HabitCheckInItem":{"properties":{"habit":{"$ref":"#/components/schemas/HabitDefinitionResponse"},"logged":{"type":"boolean","title":"Logged"},"amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Amount"},"log_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Log Id"}},"type":"object","required":["habit","logged"],"title":"HabitCheckInItem","description":"One habit's status for a given date."},"HabitCorrelation":{"properties":{"habit_name":{"type":"string","title":"Habit Name"},"habit_emoji":{"type":"string","title":"Habit Emoji"},"avg_mood_with":{"type":"number","title":"Avg Mood With"},"avg_mood_without":{"type":"number","title":"Avg Mood Without"},"delta":{"type":"number","title":"Delta"},"days_with":{"type":"integer","title":"Days With"},"days_without":{"type":"integer","title":"Days Without"}},"type":"object","required":["habit_name","habit_emoji","avg_mood_with","avg_mood_without","delta","days_with","days_without"],"title":"HabitCorrelation"},"HabitCorrelationsResult":{"properties":{"habits":{"items":{"$ref":"#/components/schemas/HabitCorrelation"},"type":"array","title":"Habits"},"description":{"type":"string","title":"Description"}},"type":"object","required":["habits","description"],"title":"HabitCorrelationsResult"},"HabitCreateRequest":{"properties":{"name":{"type":"string","maxLength":50,"minLength":1,"title":"Name"},"emoji":{"type":"string","maxLength":32,"minLength":1,"title":"Emoji"},"unit":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Unit"},"default_target":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Default Target"},"trigger":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Trigger"}},"type":"object","required":["name","emoji"],"title":"HabitCreateRequest"},"HabitDefinitionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"emoji":{"type":"string","title":"Emoji"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unit"},"default_target":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Default Target"},"is_preset":{"type":"boolean","title":"Is Preset"},"is_active":{"type":"boolean","title":"Is Active"},"sort_order":{"type":"integer","title":"Sort Order"},"weekly_target":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Weekly Target"},"trigger":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trigger"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"full_target":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Full Target"},"can_escalate":{"type":"boolean","title":"Can Escalate","default":false}},"type":"object","required":["id","name","emoji","unit","default_target","is_preset","is_active","sort_order","weekly_target","trigger","created_at"],"title":"HabitDefinitionResponse"},"HabitHistoryResponse":{"properties":{"days":{"items":{"$ref":"#/components/schemas/DayHistory"},"type":"array","title":"Days"},"period_days":{"type":"integer","title":"Period Days"}},"type":"object","required":["days","period_days"],"title":"HabitHistoryResponse"},"HabitInsightListResponse":{"properties":{"insights":{"items":{"$ref":"#/components/schemas/HabitInsightResponse"},"type":"array","title":"Insights"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["insights","total"],"title":"HabitInsightListResponse"},"HabitInsightResponse":{"properties":{"id":{"type":"integer","title":"Id"},"content":{"type":"string","title":"Content"},"model_used":{"type":"string","title":"Model Used"},"cost":{"type":"number","title":"Cost"},"week_start":{"type":"string","format":"date","title":"Week Start"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","content","model_used","cost","week_start","created_at"],"title":"HabitInsightResponse"},"HabitLinkRequest":{"properties":{"habit_id":{"type":"integer","title":"Habit Id"}},"type":"object","required":["habit_id"],"title":"HabitLinkRequest"},"HabitLogRequest":{"properties":{"habit_id":{"type":"integer","title":"Habit Id"},"completed":{"type":"boolean","title":"Completed","default":true},"amount":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Amount"},"log_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Log Date"}},"type":"object","required":["habit_id"],"title":"HabitLogRequest"},"HabitLogResponse":{"properties":{"id":{"type":"integer","title":"Id"},"habit_id":{"type":"integer","title":"Habit Id"},"log_date":{"type":"string","format":"date","title":"Log Date"},"completed":{"type":"boolean","title":"Completed"},"amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Amount"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","habit_id","log_date","completed","amount","created_at"],"title":"HabitLogResponse"},"HabitStreakInfo":{"properties":{"habit_id":{"type":"integer","title":"Habit Id"},"habit_name":{"type":"string","title":"Habit Name"},"habit_emoji":{"type":"string","title":"Habit Emoji"},"current_streak":{"type":"integer","title":"Current Streak"},"longest_streak":{"type":"integer","title":"Longest Streak"}},"type":"object","required":["habit_id","habit_name","habit_emoji","current_streak","longest_streak"],"title":"HabitStreakInfo"},"HabitUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":50,"minLength":1},{"type":"null"}],"title":"Name"},"emoji":{"anyOf":[{"type":"string","maxLength":32,"minLength":1},{"type":"null"}],"title":"Emoji"},"unit":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Unit"},"default_target":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Default Target"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"sort_order":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Sort Order"},"weekly_target":{"anyOf":[{"type":"integer","maximum":7.0,"minimum":1.0},{"type":"null"}],"title":"Weekly Target"},"trigger":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Trigger"}},"type":"object","title":"HabitUpdateRequest"},"InternalThemeRequest":{"properties":{"user_id":{"type":"string","title":"User Id","description":"Target user ID"},"custom_colors":{"type":"string","title":"Custom Colors","description":"JSON string with css + name + font"},"theme_preset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Theme Preset","description":"Optional preset ID to set"}},"type":"object","required":["user_id","custom_colors"],"title":"InternalThemeRequest"},"ItemBankResponse":{"properties":{"instrument":{"type":"string","title":"Instrument"},"items":{"items":{"$ref":"#/components/schemas/PersonalityItem"},"type":"array","title":"Items"}},"type":"object","required":["instrument","items"],"title":"ItemBankResponse"},"JournalCreateRequest":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Title"},"content":{"type":"string","maxLength":50000,"minLength":1,"title":"Content"},"mood_emoji":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Mood Emoji"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":10},{"type":"null"}],"title":"Tags"}},"type":"object","required":["content"],"title":"JournalCreateRequest"},"JournalEntryBrief":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"content_preview":{"type":"string","title":"Content Preview"},"mood_emoji":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mood Emoji"},"mood_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mood Label"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"reflection_count":{"type":"integer","title":"Reflection Count"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","title","content_preview","mood_emoji","mood_label","tags","reflection_count","created_at"],"title":"JournalEntryBrief","description":"Lightweight version for list views — no full content or reflections."},"JournalEntryResponse":{"properties":{"id":{"type":"integer","title":"Id"},"user_id":{"type":"string","title":"User Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"content":{"type":"string","title":"Content"},"mood_emoji":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mood Emoji"},"mood_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mood Label"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","default":[]},"reflections":{"items":{"$ref":"#/components/schemas/JournalReflectionResponse"},"type":"array","title":"Reflections"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","user_id","title","content","mood_emoji","mood_label","reflections","created_at","updated_at"],"title":"JournalEntryResponse"},"JournalListResponse":{"properties":{"entries":{"items":{"$ref":"#/components/schemas/JournalEntryBrief"},"type":"array","title":"Entries"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["entries","total"],"title":"JournalListResponse"},"JournalReflectResponse":{"properties":{"reflection":{"$ref":"#/components/schemas/JournalReflectionResponse"},"remaining":{"type":"integer","title":"Remaining"}},"type":"object","required":["reflection","remaining"],"title":"JournalReflectResponse"},"JournalReflectionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"content":{"type":"string","title":"Content"},"model_used":{"type":"string","title":"Model Used"},"cost":{"type":"number","title":"Cost"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","content","model_used","cost","created_at"],"title":"JournalReflectionResponse"},"LifeSettingsResponse":{"properties":{"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"timezone":{"type":"string","title":"Timezone"},"theme":{"type":"string","title":"Theme"},"theme_opacity":{"type":"number","title":"Theme Opacity"},"theme_preset":{"type":"string","title":"Theme Preset","default":"default"},"med_length":{"type":"string","title":"Med Length","default":"medium"},"med_voice":{"type":"string","title":"Med Voice","default":"serene"},"med_ambience":{"type":"string","title":"Med Ambience","default":"rain"},"onboarding_completed":{"type":"boolean","title":"Onboarding Completed","default":false},"custom_colors":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Colors"}},"type":"object","required":["display_name","timezone","theme","theme_opacity"],"title":"LifeSettingsResponse"},"LifeSettingsUpdate":{"properties":{"display_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Display Name"},"timezone":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Timezone"},"theme":{"anyOf":[{"type":"string","maxLength":30},{"type":"null"}],"title":"Theme"},"theme_opacity":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Theme Opacity"},"theme_preset":{"anyOf":[{"type":"string","maxLength":30},{"type":"null"}],"title":"Theme Preset"},"med_length":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Med Length"},"med_voice":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Med Voice"},"med_ambience":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Med Ambience"},"custom_colors":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}],"title":"Custom Colors"}},"type":"object","title":"LifeSettingsUpdate","description":"Partial update — all fields optional."},"LinkedHabitResponse":{"properties":{"habit_id":{"type":"integer","title":"Habit Id"},"habit_name":{"type":"string","title":"Habit Name"},"habit_emoji":{"type":"string","title":"Habit Emoji"},"days_completed":{"type":"integer","title":"Days Completed"},"days_total":{"type":"integer","title":"Days Total"}},"type":"object","required":["habit_id","habit_name","habit_emoji","days_completed","days_total"],"title":"LinkedHabitResponse"},"LoginRequest":{"properties":{"email":{"type":"string","title":"Email"},"role":{"type":"string","title":"Role","default":"user"}},"type":"object","required":["email"],"title":"LoginRequest"},"LoginResponse":{"properties":{"token":{"type":"string","title":"Token"},"user":{"additionalProperties":true,"type":"object","title":"User"},"refresh_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refresh Token"}},"type":"object","required":["token","user"],"title":"LoginResponse"},"MeditationEffectivenessResult":{"properties":{"avg_delta":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Delta"},"sessions_analyzed":{"type":"integer","title":"Sessions Analyzed"},"improved":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Improved"},"unchanged":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Unchanged"},"worsened":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Worsened"},"description":{"type":"string","title":"Description"}},"type":"object","required":["avg_delta","sessions_analyzed","description"],"title":"MeditationEffectivenessResult"},"MeditationLength":{"type":"string","enum":["quick","short","medium","long"],"title":"MeditationLength"},"MeditationStatsResponse":{"properties":{"total_sessions":{"type":"integer","title":"Total Sessions"},"total_minutes":{"type":"integer","title":"Total Minutes"},"current_streak":{"type":"integer","title":"Current Streak"},"longest_streak":{"type":"integer","title":"Longest Streak"}},"type":"object","required":["total_sessions","total_minutes","current_streak","longest_streak"],"title":"MeditationStatsResponse"},"MeditationType":{"type":"string","enum":["breathing","body_scan","loving_kindness","visualization","gratitude","stress_relief"],"title":"MeditationType"},"MessageResponse":{"properties":{"message":{"type":"string","title":"Message"}},"type":"object","required":["message"],"title":"MessageResponse"},"MilestoneCreateRequest":{"properties":{"title":{"type":"string","maxLength":200,"minLength":1,"title":"Title"}},"type":"object","required":["title"],"title":"MilestoneCreateRequest"},"MilestoneResponse":{"properties":{"id":{"type":"integer","title":"Id"},"goal_id":{"type":"integer","title":"Goal Id"},"title":{"type":"string","title":"Title"},"is_completed":{"type":"boolean","title":"Is Completed"},"sort_order":{"type":"integer","title":"Sort Order"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","goal_id","title","is_completed","sort_order","created_at","completed_at"],"title":"MilestoneResponse"},"MilestoneUpdateRequest":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Title"},"is_completed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Completed"},"sort_order":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Sort Order"}},"type":"object","title":"MilestoneUpdateRequest"},"MoodAfterRequest":{"properties":{"emoji":{"type":"string","maxLength":10,"minLength":1,"title":"Emoji"}},"type":"object","required":["emoji"],"title":"MoodAfterRequest"},"MoodEmoji":{"type":"string","enum":["😊","😢","😠","😰","😴","🤩","😐","🥰","😤","🤔","😌","💪"],"title":"MoodEmoji"},"MoodEntryResponse":{"properties":{"id":{"type":"integer","title":"Id"},"user_id":{"type":"string","title":"User Id"},"emoji":{"type":"string","title":"Emoji"},"label":{"type":"string","title":"Label"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","user_id","emoji","label","note","created_at"],"title":"MoodEntryResponse"},"MoodForecastResponse":{"properties":{"period_days":{"type":"integer","title":"Period Days"},"total_entries":{"type":"integer","title":"Total Entries"},"trend":{"$ref":"#/components/schemas/TrendResult"},"day_of_week":{"$ref":"#/components/schemas/DayOfWeekResult"},"forecast":{"$ref":"#/components/schemas/ForecastResult"},"habit_correlations":{"$ref":"#/components/schemas/HabitCorrelationsResult"},"volatility":{"$ref":"#/components/schemas/VolatilityResult"},"meditation_effectiveness":{"$ref":"#/components/schemas/MeditationEffectivenessResult"}},"type":"object","required":["period_days","total_entries","trend","day_of_week","forecast","habit_correlations","volatility","meditation_effectiveness"],"title":"MoodForecastResponse"},"MoodHistoryResponse":{"properties":{"entries":{"items":{"$ref":"#/components/schemas/MoodEntryResponse"},"type":"array","title":"Entries"},"total":{"type":"integer","title":"Total"},"days":{"type":"integer","title":"Days"}},"type":"object","required":["entries","total","days"],"title":"MoodHistoryResponse"},"MoodLogRequest":{"properties":{"emoji":{"$ref":"#/components/schemas/MoodEmoji"},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Note"}},"type":"object","required":["emoji"],"title":"MoodLogRequest"},"MoodLogResponse":{"properties":{"entry":{"$ref":"#/components/schemas/MoodEntryResponse"},"streak":{"type":"integer","title":"Streak"},"today_count":{"type":"integer","title":"Today Count"},"suggestion":{"anyOf":[{"$ref":"#/components/schemas/MoodSuggestion"},{"type":"null"}]}},"type":"object","required":["entry","streak","today_count"],"title":"MoodLogResponse"},"MoodStreakResponse":{"properties":{"streak_days":{"type":"integer","title":"Streak Days"},"total_logs":{"type":"integer","title":"Total Logs"}},"type":"object","required":["streak_days","total_logs"],"title":"MoodStreakResponse"},"MoodSuggestion":{"properties":{"type":{"type":"string","title":"Type"},"message":{"type":"string","title":"Message"}},"type":"object","required":["type","message"],"title":"MoodSuggestion"},"OAuthLoginRequest":{"properties":{"provider":{"type":"string","title":"Provider"},"code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"},"credential":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credential"},"redirect_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Redirect Uri"}},"type":"object","required":["provider"],"title":"OAuthLoginRequest","description":"Universal OAuth login — provider sends auth code or credential."},"PasswordLoginRequest":{"properties":{"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"PasswordLoginRequest"},"PersonalityItem":{"properties":{"id":{"type":"integer","title":"Id"},"kind":{"type":"string","title":"Kind"},"left":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Left"},"right":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Right"},"factor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Factor"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"}},"type":"object","required":["id","kind"],"title":"PersonalityItem"},"PersonalityResponse":{"properties":{"completed":{"type":"boolean","title":"Completed"},"instrument":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instrument"},"type_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type Code"},"archetype":{"anyOf":[{"$ref":"#/components/schemas/Archetype"},{"type":"null"}]},"axes":{"anyOf":[{"$ref":"#/components/schemas/AxisVector"},{"type":"null"}]},"big5":{"anyOf":[{"$ref":"#/components/schemas/Big5Vector"},{"type":"null"}]},"big5_derived":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Big5 Derived"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["completed"],"title":"PersonalityResponse"},"PersonalizationResponse":{"properties":{"player_type":{"type":"string","title":"Player Type"},"challenge_difficulty":{"type":"string","title":"Challenge Difficulty"},"gamification_emphasis":{"type":"number","title":"Gamification Emphasis"},"personalization_source":{"type":"string","title":"Personalization Source"}},"type":"object","required":["player_type","challenge_difficulty","gamification_emphasis","personalization_source"],"title":"PersonalizationResponse"},"PersonalizationUpdate":{"properties":{"player_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Player Type","description":"achiever|explorer|socializer"},"challenge_difficulty":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Challenge Difficulty","description":"easy|medium|hard"},"gamification_emphasis":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Gamification Emphasis"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","description":"user|zugabot"}},"type":"object","title":"PersonalizationUpdate"},"PreferencesRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"quiet_start":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quiet Start"},"quiet_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quiet End"},"reminder_hour":{"type":"integer","title":"Reminder Hour","default":9},"streak_warnings":{"type":"boolean","title":"Streak Warnings","default":true},"daily_nudges":{"type":"boolean","title":"Daily Nudges","default":true},"milestone_alerts":{"type":"boolean","title":"Milestone Alerts","default":true}},"type":"object","title":"PreferencesRequest"},"PreferencesResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"quiet_start":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quiet Start"},"quiet_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quiet End"},"reminder_hour":{"type":"integer","title":"Reminder Hour"},"streak_warnings":{"type":"boolean","title":"Streak Warnings"},"daily_nudges":{"type":"boolean","title":"Daily Nudges"},"milestone_alerts":{"type":"boolean","title":"Milestone Alerts"}},"type":"object","required":["enabled","quiet_start","quiet_end","reminder_hour","streak_warnings","daily_nudges","milestone_alerts"],"title":"PreferencesResponse"},"PrestigeResponse":{"properties":{"new_prestige_level":{"type":"integer","title":"New Prestige Level"},"prestige_multiplier":{"type":"number","title":"Prestige Multiplier"},"badge":{"$ref":"#/components/schemas/BadgeResponse"}},"type":"object","required":["new_prestige_level","prestige_multiplier","badge"],"title":"PrestigeResponse"},"ReactRequest":{"properties":{"reaction":{"type":"string","enum":["like","skip","save"],"title":"Reaction","description":"like | skip | save"}},"type":"object","required":["reaction"],"title":"ReactRequest"},"RecommitRequest":{"properties":{"new_deadline":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"New Deadline"}},"type":"object","title":"RecommitRequest"},"RefreshRequest":{"properties":{"refresh_token":{"type":"string","title":"Refresh Token"}},"type":"object","required":["refresh_token"],"title":"RefreshRequest"},"RefreshResponse":{"properties":{"token":{"type":"string","title":"Token"},"refresh_token":{"type":"string","title":"Refresh Token"}},"type":"object","required":["token","refresh_token"],"title":"RefreshResponse"},"RegisterRequest":{"properties":{"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"RegisterRequest"},"RemainingResponse":{"properties":{"used":{"type":"integer","title":"Used"},"limit":{"type":"integer","title":"Limit"},"remaining":{"type":"integer","title":"Remaining"}},"type":"object","required":["used","limit","remaining"],"title":"RemainingResponse"},"ResetPasswordRequest":{"properties":{"token":{"type":"string","title":"Token"},"password":{"type":"string","title":"Password"}},"type":"object","required":["token","password"],"title":"ResetPasswordRequest"},"SearchResponse":{"properties":{"cards":{"items":{"$ref":"#/components/schemas/CardOut"},"type":"array","title":"Cards"}},"type":"object","required":["cards"],"title":"SearchResponse"},"SelfDeleteRequest":{"properties":{"confirm":{"type":"string","title":"Confirm"}},"type":"object","required":["confirm"],"title":"SelfDeleteRequest"},"SessionBrief":{"properties":{"id":{"type":"integer","title":"Id"},"type":{"type":"string","title":"Type"},"length":{"type":"string","title":"Length","default":"medium"},"duration_seconds":{"type":"integer","title":"Duration Seconds","default":0},"title":{"type":"string","title":"Title"},"is_favorite":{"type":"boolean","title":"Is Favorite"},"mood_after":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mood After"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","type","title","is_favorite","mood_after","created_at"],"title":"SessionBrief"},"SessionListResponse":{"properties":{"sessions":{"items":{"$ref":"#/components/schemas/SessionBrief"},"type":"array","title":"Sessions"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["sessions","total"],"title":"SessionListResponse"},"SessionNoteListResponse":{"properties":{"notes":{"items":{"$ref":"#/components/schemas/SessionNoteResponse"},"type":"array","title":"Notes"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["notes","total"],"title":"SessionNoteListResponse"},"SessionNoteResponse":{"properties":{"id":{"type":"integer","title":"Id"},"themes":{"type":"string","title":"Themes"},"patterns":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Patterns"},"follow_up":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Follow Up"},"mood_snapshot":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mood Snapshot"},"mood_before":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mood Before"},"mood_after":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mood After"},"rating":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rating"},"message_count":{"type":"integer","title":"Message Count"},"cost":{"type":"number","title":"Cost"},"provider":{"type":"string","title":"Provider"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","themes","patterns","follow_up","mood_snapshot","mood_before","mood_after","rating","message_count","cost","provider","created_at","updated_at"],"title":"SessionNoteResponse"},"SessionNoteUpdateRequest":{"properties":{"themes":{"anyOf":[{"type":"string","maxLength":5000,"minLength":1},{"type":"null"}],"title":"Themes"},"patterns":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"title":"Patterns"},"follow_up":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"title":"Follow Up"}},"type":"object","title":"SessionNoteUpdateRequest"},"SessionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"type":{"type":"string","title":"Type"},"length":{"type":"string","title":"Length","default":"medium"},"duration_seconds":{"type":"integer","title":"Duration Seconds","default":0},"ambience":{"type":"string","title":"Ambience"},"voice":{"type":"string","title":"Voice"},"focus":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Focus"},"title":{"type":"string","title":"Title"},"transcript":{"type":"string","title":"Transcript"},"audio_filename":{"type":"string","title":"Audio Filename"},"model_used":{"type":"string","title":"Model Used"},"tts_model":{"type":"string","title":"Tts Model"},"cost":{"type":"number","title":"Cost"},"status":{"type":"string","title":"Status","default":"ready"},"mood_before":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mood Before"},"mood_after":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mood After"},"is_favorite":{"type":"boolean","title":"Is Favorite"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","type","ambience","voice","focus","title","transcript","audio_filename","model_used","tts_model","cost","mood_before","mood_after","is_favorite","created_at"],"title":"SessionResponse"},"ShareStatus":{"properties":{"sharing":{"type":"boolean","title":"Sharing"},"can_share":{"type":"boolean","title":"Can Share"}},"type":"object","required":["sharing","can_share"],"title":"ShareStatus"},"ShareUpdate":{"properties":{"enabled":{"type":"boolean","title":"Enabled","description":"Opt in (True) or out (False) of sharing the coarse vector with Zugabot"}},"type":"object","required":["enabled"],"title":"ShareUpdate"},"SourceDetailResponse":{"properties":{"source":{"$ref":"#/components/schemas/SourceOut"},"cards":{"items":{"$ref":"#/components/schemas/CardOut"},"type":"array","title":"Cards"}},"type":"object","required":["source","cards"],"title":"SourceDetailResponse"},"SourceOut":{"properties":{"id":{"type":"integer","title":"Id"},"key":{"type":"string","title":"Key"},"kind":{"type":"string","title":"Kind"},"title":{"type":"string","title":"Title"},"author":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author"},"cover_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Url"},"read_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Read Url"},"year":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Year"},"blurb":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Blurb"}},"type":"object","required":["id","key","kind","title"],"title":"SourceOut"},"SourceWithCount":{"properties":{"id":{"type":"integer","title":"Id"},"key":{"type":"string","title":"Key"},"kind":{"type":"string","title":"Kind"},"title":{"type":"string","title":"Title"},"author":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author"},"cover_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Url"},"read_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Read Url"},"year":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Year"},"blurb":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Blurb"},"idea_count":{"type":"integer","title":"Idea Count","default":0}},"type":"object","required":["id","key","kind","title"],"title":"SourceWithCount"},"SourcesResponse":{"properties":{"sources":{"items":{"$ref":"#/components/schemas/SourceWithCount"},"type":"array","title":"Sources"}},"type":"object","required":["sources"],"title":"SourcesResponse"},"StashResponse":{"properties":{"cards":{"items":{"$ref":"#/components/schemas/CardOut"},"type":"array","title":"Cards"}},"type":"object","required":["cards"],"title":"StashResponse"},"StationarityResult":{"properties":{"raw_p_value":{"type":"number","title":"Raw P Value"},"raw_stationary":{"type":"boolean","title":"Raw Stationary"},"diff_p_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Diff P Value"},"diff_stationary":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Diff Stationary"},"recommended_d":{"type":"integer","title":"Recommended D"}},"type":"object","required":["raw_p_value","raw_stationary","recommended_d"],"title":"StationarityResult"},"SubmitRequest":{"properties":{"responses":{"additionalProperties":{"type":"integer"},"type":"object","title":"Responses","description":"OEJTS+N answers, 1-5 per item id"},"consent":{"type":"boolean","title":"Consent","description":"Explicit opt-in to take + store the assessment"}},"type":"object","required":["responses","consent"],"title":"SubmitRequest"},"SubscribeRequest":{"properties":{"endpoint":{"type":"string","title":"Endpoint"},"p256dh":{"type":"string","title":"P256Dh"},"auth":{"type":"string","title":"Auth"}},"type":"object","required":["endpoint","p256dh","auth"],"title":"SubscribeRequest"},"TherapistChatRequest":{"properties":{"messages":{"items":{"$ref":"#/components/schemas/TherapistMessage"},"type":"array","minItems":1,"title":"Messages"}},"type":"object","required":["messages"],"title":"TherapistChatRequest"},"TherapistChatResponse":{"properties":{"content":{"type":"string","title":"Content"},"message_index":{"type":"integer","title":"Message Index"},"session_messages_remaining":{"type":"integer","title":"Session Messages Remaining"},"cost":{"type":"number","title":"Cost"},"crisis_detected":{"type":"boolean","title":"Crisis Detected","default":false},"mood":{"type":"string","enum":["happy","sad","angry","surprised","relaxed","neutral"],"title":"Mood","default":"neutral"},"mood_intensity":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Mood Intensity","default":0.0}},"type":"object","required":["content","message_index","session_messages_remaining","cost"],"title":"TherapistChatResponse"},"TherapistEndSessionRequest":{"properties":{"messages":{"items":{"$ref":"#/components/schemas/TherapistMessage"},"type":"array","minItems":1,"title":"Messages"},"mood_before":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Mood Before"},"mood_after":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Mood After"},"rating":{"anyOf":[{"type":"integer","maximum":5.0,"minimum":1.0},{"type":"null"}],"title":"Rating"}},"type":"object","required":["messages"],"title":"TherapistEndSessionRequest"},"TherapistMessage":{"properties":{"role":{"type":"string","enum":["user","assistant"],"title":"Role"},"content":{"type":"string","maxLength":10000,"title":"Content"}},"type":"object","required":["role","content"],"title":"TherapistMessage","description":"A single message in therapist conversation. Only user/assistant roles allowed."},"TherapistSpeakRequest":{"properties":{"text":{"type":"string","maxLength":2000,"minLength":1,"title":"Text","description":"Assistant text to speak"},"voice":{"type":"string","title":"Voice","description":"Cartesia voice UUID. Empty = use server default.","default":""}},"type":"object","required":["text"],"title":"TherapistSpeakRequest","description":"Request to synthesize an assistant utterance to audio.\n\n`voice` is a Cartesia voice UUID (browse at https://play.cartesia.ai/).\nWhen empty (the default), the BE falls through to settings.cartesia_voice_id\nand then to CARTESIA_DEFAULT_VOICE — the named friendly key \"calm-female\"\nused to be passed through here but Cartesia rejected it because it expects\na real UUID, not a label."},"TherapistStartersResponse":{"properties":{"starters":{"items":{"$ref":"#/components/schemas/ConversationStarter"},"type":"array","title":"Starters"}},"type":"object","required":["starters"],"title":"TherapistStartersResponse"},"TherapistStatusResponse":{"properties":{"sessions_used":{"type":"integer","title":"Sessions Used"},"sessions_limit":{"type":"integer","title":"Sessions Limit"},"sessions_remaining":{"type":"integer","title":"Sessions Remaining"},"is_first_session":{"type":"boolean","title":"Is First Session"}},"type":"object","required":["sessions_used","sessions_limit","sessions_remaining","is_first_session"],"title":"TherapistStatusResponse"},"TherapistTranscribeResponse":{"properties":{"text":{"type":"string","title":"Text","description":"Transcribed text"},"duration_sec":{"type":"number","title":"Duration Sec","description":"Audio duration in seconds (Whisper-reported)"},"cost_usd":{"type":"number","title":"Cost Usd","description":"USD cost of the transcription call"}},"type":"object","required":["text","duration_sec","cost_usd"],"title":"TherapistTranscribeResponse","description":"Whisper STT result. Audio is sent as multipart, not in this schema."},"TodayResponse":{"properties":{"cards":{"items":{"$ref":"#/components/schemas/CardOut"},"type":"array","title":"Cards"},"needs_personality":{"type":"boolean","title":"Needs Personality"}},"type":"object","required":["cards","needs_personality"],"title":"TodayResponse"},"TrendResult":{"properties":{"slope":{"type":"number","title":"Slope"},"direction":{"type":"string","title":"Direction"},"description":{"type":"string","title":"Description"},"avg_valence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Valence"},"data_points":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Data Points"}},"type":"object","required":["slope","direction","description"],"title":"TrendResult"},"UserResponse":{"properties":{"id":{"type":"string","title":"Id"},"email":{"type":"string","title":"Email"},"role":{"type":"string","title":"Role"},"is_admin":{"type":"boolean","title":"Is Admin"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"apps":{"items":{"type":"string"},"type":"array","title":"Apps","default":[]}},"type":"object","required":["id","email","role","is_admin"],"title":"UserResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VerifyEmailRequest":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"VerifyEmailRequest"},"VoiceType":{"type":"string","enum":["serene","gentle","whisper"],"title":"VoiceType"},"VolatilityResult":{"properties":{"current_volatility":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Volatility"},"previous_volatility":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Previous Volatility"},"change":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change"},"direction":{"type":"string","title":"Direction"},"level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Level"},"description":{"type":"string","title":"Description"}},"type":"object","required":["current_volatility","direction","description"],"title":"VolatilityResult"},"WeeklyQuestResponse":{"properties":{"quest_key":{"type":"string","title":"Quest Key"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"xp_reward":{"type":"integer","title":"Xp Reward"},"is_completed":{"type":"boolean","title":"Is Completed"}},"type":"object","required":["quest_key","title","description","xp_reward","is_completed"],"title":"WeeklyQuestResponse"},"WeeklyTargetItem":{"properties":{"habit_id":{"type":"integer","title":"Habit Id"},"habit_name":{"type":"string","title":"Habit Name"},"habit_emoji":{"type":"string","title":"Habit Emoji"},"weekly_target":{"type":"integer","title":"Weekly Target"},"this_week_count":{"type":"integer","title":"This Week Count"},"progress_pct":{"type":"number","title":"Progress Pct"}},"type":"object","required":["habit_id","habit_name","habit_emoji","weekly_target","this_week_count","progress_pct"],"title":"WeeklyTargetItem"},"WeeklyTargetsResponse":{"properties":{"habits":{"items":{"$ref":"#/components/schemas/WeeklyTargetItem"},"type":"array","title":"Habits"},"week_start":{"type":"string","format":"date","title":"Week Start"}},"type":"object","required":["habits","week_start"],"title":"WeeklyTargetsResponse"},"XPGainResponse":{"properties":{"xp_gained":{"type":"integer","title":"Xp Gained"},"new_total":{"type":"integer","title":"New Total"},"level_up":{"type":"boolean","title":"Level Up"},"new_level":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"New Level"},"new_badges":{"items":{"$ref":"#/components/schemas/BadgeResponse"},"type":"array","title":"New Badges"},"bonus_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bonus Label"},"bonus_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bonus Tier"},"bonus_multiplier":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Bonus Multiplier"},"streak_freeze_used":{"type":"boolean","title":"Streak Freeze Used","default":false}},"type":"object","required":["xp_gained","new_total","level_up","new_level","new_badges"],"title":"XPGainResponse"},"XPStatusResponse":{"properties":{"total_xp":{"type":"integer","title":"Total Xp"},"level":{"type":"integer","title":"Level"},"level_name":{"type":"string","title":"Level Name"},"xp_for_next_level":{"type":"integer","title":"Xp For Next Level"},"xp_progress_in_level":{"type":"integer","title":"Xp Progress In Level"},"current_streak_days":{"type":"integer","title":"Current Streak Days"},"longest_streak_days":{"type":"integer","title":"Longest Streak Days"},"streak_multiplier":{"type":"number","title":"Streak Multiplier"},"prestige_level":{"type":"integer","title":"Prestige Level","default":0},"prestige_multiplier":{"type":"number","title":"Prestige Multiplier","default":1.0},"can_prestige":{"type":"boolean","title":"Can Prestige","default":false},"streak_freezes":{"type":"integer","title":"Streak Freezes","default":0},"streak_freeze_used":{"type":"boolean","title":"Streak Freeze Used","default":false},"bonus_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bonus Label"},"bonus_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bonus Tier"},"consistency_30d":{"type":"integer","title":"Consistency 30D","default":0},"consistency_pct":{"type":"number","title":"Consistency Pct","default":0.0}},"type":"object","required":["total_xp","level","level_name","xp_for_next_level","xp_progress_in_level","current_streak_days","longest_streak_days","streak_multiplier"],"title":"XPStatusResponse"}}}}