{"openapi":"3.1.0","info":{"title":"Earmark API","description":"AI-powered payroll intelligence platform","version":"0.1.0"},"paths":{"/api/auth/register":{"post":{"tags":["Auth"],"summary":"Register","description":"Create a new user account.","operationId":"register_api_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/login":{"post":{"tags":["Auth"],"summary":"Login","description":"Authenticate and return JWT tokens.","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/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/refresh":{"post":{"tags":["Auth"],"summary":"Refresh","description":"Exchange a refresh token for new access + refresh tokens.","operationId":"refresh_api_auth_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/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/me":{"get":{"tags":["Auth"],"summary":"Get Me","description":"The authenticated user's profile. subscription_tier / is_premium are\nthe EFFECTIVE entitlement (highest of RevenueCat, Stripe, sponsored),\nresolved live — this is what unlocks features in the mobile app.","operationId":"get_me_api_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}},"security":[{"HTTPBearer":[]}]},"patch":{"tags":["Auth"],"summary":"Update Me","description":"Update the authenticated user's profile.","operationId":"update_me_api_auth_me_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/me/profession":{"patch":{"tags":["Auth"],"summary":"Update Profession","description":"Update the user's profession and/or employer name.","operationId":"update_profession_api_auth_me_profession_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfessionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/account":{"delete":{"tags":["Auth"],"summary":"Delete Account","description":"Permanently delete the authenticated user's account.\n\nDeletion is a single bulk DELETE so Postgres FK cascades do the work in\none statement — the previous ORM-cascade delete loaded every related\nrow (thousands of transactions) into memory and issued per-row\nDELETEs, which exceeded the mobile client's timeout for real accounts.\nFinexer consents are revoked best-effort AFTER the response, so their\nHTTP calls can never delay or block the deletion.","operationId":"delete_account_api_auth_account_delete","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAccountRequest"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/forgot-password":{"post":{"tags":["Auth"],"summary":"Forgot Password","description":"Email a 6-digit password reset code.\n\nReturns the same body and status whether or not the address is known —\nthis endpoint must not be usable to discover who has an account.","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":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/reset-password":{"post":{"tags":["Auth"],"summary":"Reset Password","description":"Set a new password using the emailed code.","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":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/verify-email":{"post":{"tags":["Auth"],"summary":"Verify Email","description":"Verify email with 6-digit code.","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":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/resend-verification":{"post":{"tags":["Auth"],"summary":"Resend Verification","description":"Resend email verification code. Rate limited to 3 per hour.","operationId":"resend_verification_api_auth_resend_verification_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/apple":{"post":{"tags":["Auth"],"summary":"Apple Auth","description":"Authenticate with Apple Sign In.","operationId":"apple_auth_api_auth_apple_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppleAuthRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/google":{"post":{"tags":["Auth"],"summary":"Google Auth","description":"Authenticate with Google Sign In.","operationId":"google_auth_api_auth_google_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleAuthRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/me/revenuecat-id":{"put":{"tags":["Auth"],"summary":"Sync Revenuecat Id","description":"Save the RevenueCat user ID on the current user's profile.\n\nCalled by the mobile app after login or first purchase so that\nwebhook events can be correlated back to the Earmark user.\n\nIDEMPOTENT, AND SAFE IN THE FIRST SECONDS OF AN ACCOUNT\nThe app calls this on every open and every login (20 Sep 2026: a 500\neight seconds after sign-up). So:\n  - the same id again writes nothing and answers 200;\n  - no id (no body, null, blank) is a 200 no-op;\n  - a replay that fails — even one that leaves the session in a failed\n    transaction — cannot turn the answer into a 500. The id is already\n    committed by then; the session is rolled back so the request's closing\n    commit is clean.","operationId":"sync_revenuecat_id_api_auth_me_revenuecat_id_put","requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/RevenueCatIdRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/me/subscription/refresh":{"post":{"tags":["Auth"],"summary":"Refresh Subscription","description":"Bring the user's tier up to date and return the EFFECTIVE tier.\n\nThe app calls this the moment a purchase or restore completes (and holds\nan \"activating\" screen until it answers paid), so a subscriber never sits\nbehind free-tier walls waiting for a webhook. Idempotent; safe to poll.\n\n1. Replays any webhook events for this user that were kept unmatched or\n   failed.\n2. Asks RevenueCat directly (when REVENUECAT_API_KEY is set).","operationId":"refresh_subscription_api_auth_me_subscription_refresh_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/onboarding/complete":{"post":{"tags":["Auth"],"summary":"Complete Onboarding","description":"Mark onboarding as complete and seed initial content — once.\n\nCalled by the mobile app after the user finishes the budget-onboarding\nstep (bank connected + goals set + budgets set). Triggers first weekly\nbriefing and challenge generation as background tasks so the home tab\nhas content immediately.\n\nIdempotent across replicas. The guard is a single atomic UPDATE on\nusers.onboarding_completed_at (NULL -> now()); only the call whose\nUPDATE matches a row spawns the background work. There is no\nSELECT-then-UPDATE: with two replicas that is exactly the race that\nproduced 8 briefing + 8 challenge model calls for one user on 17 Sep.\nThe stamp is committed before any task is scheduled, so a task can\nnever start for a call that will later lose the race. Repeat calls\nreturn the same 200 body and spawn nothing.\n\nBoth generators run independently — failure of either does NOT block\nthe onboarding response.","operationId":"complete_onboarding_api_auth_onboarding_complete_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/behaviour/corrections":{"get":{"tags":["behaviour"],"summary":"List Corrections","operationId":"list_corrections_api_behaviour_corrections_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CorrectionResponse"},"type":"array","title":"Response List Corrections Api Behaviour Corrections Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["behaviour"],"summary":"Create Correction","operationId":"create_correction_api_behaviour_corrections_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CorrectionRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CorrectionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/behaviour/corrections/{correction_id}":{"delete":{"tags":["behaviour"],"summary":"Delete Correction","operationId":"delete_correction_api_behaviour_corrections__correction_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"correction_id","in":"path","required":true,"schema":{"type":"string","title":"Correction Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/behaviour/review":{"get":{"tags":["behaviour"],"summary":"Review","operationId":"review_api_behaviour_review_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/adviser/auth/login":{"post":{"tags":["Adviser"],"summary":"Adviser Login","description":"Adviser sign-in. Issues adviser-typed JWTs carrying firm context.\n\nPassword reset is deliberately manual/admin during the pilot.","operationId":"adviser_login_api_adviser_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdviserLoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdviserTokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/auth/refresh":{"post":{"tags":["Adviser"],"summary":"Adviser Refresh","description":"Exchange an adviser refresh token for a new token pair.","operationId":"adviser_refresh_api_adviser_auth_refresh_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdviserRefreshRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdviserTokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/clients":{"get":{"tags":["Adviser"],"summary":"List Clients","description":"All consent grants for MY firm, with status/scope/sync info.","operationId":"list_clients_api_adviser_clients_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ClientGrantResponse"},"type":"array","title":"Response List Clients Api Adviser Clients Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/adviser/clients/invite":{"post":{"tags":["Adviser"],"summary":"Invite Client","description":"Create a PENDING consent grant + invite token.\n\nThe grant only becomes ACTIVE when the client accepts it via\nPOST /api/consents/{id}/accept. Email delivery is out of scope —\nthe token is returned to the adviser.","operationId":"invite_client_api_adviser_clients_invite_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__adviser__InviteRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__adviser__InviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/adviser/clients/{user_id}/summary":{"get":{"tags":["Adviser"],"summary":"Client Summary","description":"Period expenditure totals by pot/category. category_totals scope suffices.","operationId":"client_summary_api_adviser_clients__user_id__summary_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"months","in":"query","required":false,"schema":{"type":"integer","maximum":24,"minimum":1,"default":12,"title":"Months"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientSummaryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/clients/{user_id}/transactions":{"get":{"tags":["Adviser"],"summary":"Client Transactions","description":"Paginated transactions. REQUIRES full_transactions scope.","operationId":"client_transactions_api_adviser_clients__user_id__transactions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"month","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}$"},{"type":"null"}],"title":"Month"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/clients/{user_id}/export":{"get":{"tags":["Adviser"],"summary":"Client Export","description":"Category-level expenditure CSV (Month, Pot, Category, Amount).\n\nStreams directly with adviser auth — deliberately NOT the\ntmp_exports download-by-id flow, whose ids act as unauthenticated\nbearer capabilities.","operationId":"client_export_api_adviser_clients__user_id__export_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"csv","title":"Format"}},{"name":"months","in":"query","required":false,"schema":{"type":"integer","maximum":24,"minimum":1,"default":12,"title":"Months"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/clients/{user_id}/transactions/{transaction_id}/recategorise":{"post":{"tags":["Adviser"],"summary":"Recategorise Transaction","description":"Adviser recategorisation. Requires full_transactions + can_recategorise.\n\nWrites through the SAME pathway as user recategorisation\n(app.services.category_updates.apply_category_change) with\nactor=\"adviser\". User merchant rules win on conflict — see that\nmodule's docstring for the exact semantics.","operationId":"recategorise_transaction_api_adviser_clients__user_id__transactions__transaction_id__recategorise_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"transaction_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Transaction Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecategoriseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecategoriseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/clients/{user_id}/net-worth":{"get":{"tags":["Adviser"],"summary":"Client Net Worth","description":"Current position, breakdown by asset class, and snapshot history.\n\nMirrors the consumer summary arithmetic (app/api/net_worth.py) but\ndeliberately SKIPS _sync_connected_accounts — adviser reads must\nnever mutate client rows.","operationId":"client_net_worth_api_adviser_clients__user_id__net_worth_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdviserNetWorthResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/clients/{user_id}/properties":{"get":{"tags":["Adviser"],"summary":"Client Properties","description":"The client's properties with valuations — estimated value,\nmortgage, equity, valuation source/date and the HM Land Registry\nattribution. Reuses the consumer response builder (DB reads only);\nthe tier check inside valuation resolution uses the CLIENT's\nentitlement, not the adviser's.","operationId":"client_properties_api_adviser_clients__user_id__properties_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/clients/{user_id}/recurring":{"get":{"tags":["Adviser"],"summary":"Client Recurring","description":"Detected recurring bills and subscriptions — the same builder the\nconsumer Bills & Recurring screen uses (app/api/bills.py), so the\ntwo views can never disagree.","operationId":"client_recurring_api_adviser_clients__user_id__recurring_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/clients/{user_id}/income":{"get":{"tags":["Adviser"],"summary":"Client Income","description":"Income sources, payday plan and safe-to-spend.\n\nBehind its own scope. Knowing what a client EARNS is a different\ndisclosure from knowing what they spend, and a client who shared\nspending categories did not thereby agree to share their salary — so\nfull_transactions does not imply it and grants predating migration 096\nare excluded by construction.\n\nRead-only: mirrors the arithmetic the client sees in the app so an\nadviser can never quote a different figure back to them.","operationId":"client_income_api_adviser_clients__user_id__income_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientIncomeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/clients/{user_id}/exceptions":{"get":{"tags":["Adviser"],"summary":"Client Exceptions","description":"Transactions flagged for adviser review.\n\ncategory_totals suffices, deliberately: an exception is a prompt to look\nat something, and withholding it from a category-totals adviser would\nmean the client's own consent level decided whether their adviser\nnoticed a duplicate charge. The flags name the merchant and amount, which\nis the minimum that makes them actionable.","operationId":"client_exceptions_api_adviser_clients__user_id__exceptions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"months","in":"query","required":false,"schema":{"type":"integer","maximum":24,"minimum":1,"default":3,"title":"Months"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientExceptionsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/clients/{user_id}/annual-review":{"get":{"tags":["Adviser"],"summary":"Client Annual Review","description":"Last twelve months against the previous twelve, with commentary.\n\nGenerated on demand and never stored: a pack is a view of the data at a\nmoment, and a cached one would quietly disagree with the client's own\napp the first time a transaction was recategorised.","operationId":"client_annual_review_api_adviser_clients__user_id__annual_review_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"Produce the pack as at this date. Defaults to today. The window is the twelve COMPLETE calendar months before it, so a pack prepared for a meeting held last month still covers that meeting's year.","title":"As Of"},"description":"Produce the pack as at this date. Defaults to today. The window is the twelve COMPLETE calendar months before it, so a pack prepared for a meeting held last month still covers that meeting's year."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnualReviewPack"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/clients/{user_id}/annual-review/export":{"get":{"tags":["Adviser"],"summary":"Client Annual Review Export","description":"The same pack as a file. PDF for the client, CSV for the adviser.\n\nStreamed straight back under adviser auth — deliberately NOT the\ntmp_exports download-by-id flow, whose ids act as unauthenticated\nbearer capabilities and would put a client's whole financial year\nbehind a guessable URL.","operationId":"client_annual_review_export_api_adviser_clients__user_id__annual_review_export_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(pdf|csv)$","default":"pdf","title":"Format"}},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"As Of"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/clients/{user_id}/drift":{"get":{"tags":["Adviser"],"summary":"Client Drift","description":"Material changes in one client's position.\n\nEvery rule this grant permits is run; rules the grant does not cover are\nreported in `rules_not_run` rather than silently skipped, so a quiet\nclient is distinguishable from an unscannable one.","operationId":"client_drift_api_adviser_clients__user_id__drift_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"As Of"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientDriftResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/drift":{"get":{"tags":["Adviser"],"summary":"Firm Drift","description":"Who across the whole book needs attention.\n\nAUDITED PER CLIENT, not once for the firm. This endpoint reads every\nconsented client's transactions, so every one of them gets a row in\ntheir own access log. One row per scan per client is the honest count —\nit is what actually happened — which is why the scan is an on-demand\ncall rather than something a dashboard polls.","operationId":"firm_drift_api_adviser_drift_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"as_of","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"As Of"}},{"name":"only_with_alerts","in":"query","required":false,"schema":{"type":"boolean","description":"Return only clients with at least one alert. The whole point is a shortlist; set false to see the book with its quiet clients too.","default":true,"title":"Only With Alerts"},"description":"Return only clients with at least one alert. The whole point is a shortlist; set false to see the book with its quiet clients too."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FirmDriftResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/adviser/audit":{"get":{"tags":["Adviser"],"summary":"Firm Audit Log","description":"My firm's access log, newest first.","operationId":"firm_audit_log_api_adviser_audit_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AuditRow"},"title":"Response Firm Audit Log Api Adviser Audit Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/consents":{"get":{"tags":["Consents"],"summary":"List Consents","description":"All consent grants touching me, newest first.","operationId":"list_consents_api_consents_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ConsentItem"},"type":"array","title":"Response List Consents Api Consents Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/consents/{grant_id}/accept":{"post":{"tags":["Consents"],"summary":"Accept Consent","description":"Activate a pending grant — the client-side acceptance action.\n\nRequires the invite token AND that the invite is addressed to me\n(email match, or already bound to my user id).","operationId":"accept_consent_api_consents__grant_id__accept_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"grant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Grant Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__consents__AcceptRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentActionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/consents/{grant_id}/scopes":{"post":{"tags":["Consents"],"summary":"Update Consent Scopes","description":"Grant or withdraw the optional scopes on MY grant, independently of\nthe spending scope: balances_and_assets and income_and_payday.\n\nClient-only, active grants only: the scope can never be switched on\nby an adviser, an invite, or acceptance of an unrelated grant — this\nendpoint is the sole way it turns on. Withdrawing takes effect at\nthe adviser's next request.","operationId":"update_consent_scopes_api_consents__grant_id__scopes_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"grant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Grant Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScopeUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScopeUpdateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/consents/{grant_id}/revoke":{"post":{"tags":["Consents"],"summary":"Revoke Consent","description":"Revoke (or decline, if still pending) a grant that touches me.","operationId":"revoke_consent_api_consents__grant_id__revoke_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"grant_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Grant Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentActionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/banking/institutions":{"get":{"tags":["Banking"],"summary":"List Institutions","description":"List banking institutions available through Yapily.","operationId":"list_institutions_api_banking_institutions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/banking/connect":{"post":{"tags":["Banking"],"summary":"Connect Bank","description":"Initiate a bank connection via Yapily.\n\nReturns an authorisation URL — redirect the user's browser there so they\ncan log in at their bank and grant consent.","operationId":"connect_bank_api_banking_connect_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__banking__ConnectRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__banking__ConnectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/banking/callback/yapily":{"get":{"tags":["Banking"],"summary":"Yapily Callback","description":"OAuth callback hit by the bank redirect after user authorisation.\n\nStores the encrypted consent token and redirects back to the frontend.","operationId":"yapily_callback_api_banking_callback_yapily_get","parameters":[{"name":"consent","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consent"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"error","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},{"name":"error-description","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error-Description"}},{"name":"institution","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Institution"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/banking/connections":{"get":{"tags":["Banking"],"summary":"List Connections","description":"List all bank connections for the authenticated user.","operationId":"list_connections_api_banking_connections_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ConnectionResponse"},"type":"array","title":"Response List Connections Api Banking Connections Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/banking/connections/{connection_id}":{"delete":{"tags":["Banking"],"summary":"Revoke Connection","description":"Revoke a bank connection and delete its stored consent token.","operationId":"revoke_connection_api_banking_connections__connection_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"connection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Connection Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/banking/accounts":{"get":{"tags":["Banking"],"summary":"List Accounts","description":"List all bank accounts for the authenticated user.\n\nAccounts on an \"unsupported\" connection (Monzo/Starling pots — parked,\nnever synced) are excluded: they leaked into the activity account\nfilter, the support blob, and the export screen as \"Pot Account £0.00\".\nAccounts on a \"removed\" connection (user removed one account without\ndisconnecting the bank) are excluded for the same reason.\nThe outer join stays for accounts with no connection (CSV/demo imports).","operationId":"list_accounts_api_banking_accounts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/app__api__banking__AccountResponse"},"type":"array","title":"Response List Accounts Api Banking Accounts Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/banking/transactions":{"get":{"tags":["Banking"],"summary":"List Transactions","description":"List transactions with optional filters and pagination.","operationId":"list_transactions_api_banking_transactions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Per Page"}},{"name":"account_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Account Id"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"To"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/banking/transactions/categories":{"get":{"tags":["Banking"],"summary":"List Categories","description":"Return assignable transaction categories with display names and emojis.\n\nThe six new codes (tax, travel, cash, debt_repayments,\npayments_to_people, childcare_and_education) only for a user with\nCLASSIFY_V2; everyone else gets the 19 build 29 knows\n(classification/legacy_gate.py).","operationId":"list_categories_api_banking_transactions_categories_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CategoryInfoResponse"},"type":"array","title":"Response List Categories Api Banking Transactions Categories Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/banking/transactions/{transaction_id}/category":{"patch":{"tags":["Banking"],"summary":"Update Transaction Category","description":"Reassign a transaction's category and optionally create a merchant→category\noverride so future transactions from the same merchant are auto-categorised.\n\nThe write itself goes through app.services.category_updates so the\nadviser recategorisation endpoint shares the exact same pathway.","operationId":"update_transaction_category_api_banking_transactions__transaction_id__category_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"transaction_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Transaction Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCategoryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCategoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/banking/detect-transfers":{"post":{"tags":["Banking"],"summary":"Detect Transfers","description":"Detect internal transfers between the user's own bank accounts.\nMarks matching debit/credit pairs as is_internal_transfer=True.","operationId":"detect_transfers_api_banking_detect_transfers_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectTransfersResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/banking/bill-splits":{"get":{"tags":["Banking"],"summary":"List Bill Splits","description":"List all bill splits for the current user.","operationId":"list_bill_splits_api_banking_bill_splits_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BillSplitResponse"},"type":"array","title":"Response List Bill Splits Api Banking Bill Splits Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Banking"],"summary":"Create Bill Split","description":"Create or upsert a bill split for a merchant.","operationId":"create_bill_split_api_banking_bill_splits_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillSplitRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillSplitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/banking/bill-splits/{split_id}":{"patch":{"tags":["Banking"],"summary":"Update Bill Split","description":"Update a bill split's percentage or label.","operationId":"update_bill_split_api_banking_bill_splits__split_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"split_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Split Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillSplitUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillSplitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Banking"],"summary":"Delete Bill Split","description":"Remove a bill split.","operationId":"delete_bill_split_api_banking_bill_splits__split_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"split_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Split Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/banking/sync/{connection_id}":{"post":{"tags":["Banking"],"summary":"Sync Transactions","description":"Sync accounts and transactions from a connected bank via Yapily.\n\nFetches the latest accounts, balances, and transactions, upserts them\ninto the database, and deduplicates by external_id.","operationId":"sync_transactions_api_banking_sync__connection_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"connection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Connection Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__banking__SyncResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/banking/seed-demo-data":{"post":{"tags":["Banking"],"summary":"Seed Demo Data","description":"Import Monzo CSV transactions as demo data for a user.\n\nCreates a demo bank connection and account, parses the CSV,\nand stores all transactions. If demo data already exists for\nthis user, it is cleared and re-seeded.","operationId":"seed_demo_data_api_banking_seed_demo_data_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeedRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__banking__SeedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/banking/demo-summary/{user_id}":{"get":{"tags":["Banking"],"summary":"Get Demo Summary","description":"Return the seeded demo account info and transaction summary\nwithout re-importing. Used by the onboarding flow after \"connecting\".","operationId":"get_demo_summary_api_banking_demo_summary__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemoSummaryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/banking/purge-demo":{"post":{"tags":["Banking"],"summary":"Purge Demo Data","description":"Delete all demo transactions, accounts, and connections for the current user.\nOnly removes data where source='demo' or provider='demo'.","operationId":"purge_demo_data_api_banking_purge_demo_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/analysis/status/{user_id}":{"get":{"tags":["Analysis"],"summary":"Analysis Status","description":"Check whether transactions and analysis exist for a user (no computation).","operationId":"analysis_status_api_analysis_status__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalysisStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analysis/run":{"post":{"tags":["Analysis"],"summary":"Run User Analysis","description":"Run the Earmark intelligence engine on the authenticated user's\nsynced bank transactions and store the result.","operationId":"run_user_analysis_api_analysis_run_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalysisResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/analysis/latest":{"get":{"tags":["Analysis"],"summary":"Get Latest Analysis","description":"Return the most recent analysis for the authenticated user.","operationId":"get_latest_analysis_api_analysis_latest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalysisResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/analysis/insights":{"get":{"tags":["Analysis"],"summary":"Get Ai Insights","description":"Generate insight cards from the user's data.\nFree tier: rule-based insights (zero AI cost, cached 6h).\nPaid tier: AI-powered insights (cached 6h).","operationId":"get_ai_insights_api_analysis_insights_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/analysis/financial-profile/{user_id}":{"post":{"tags":["Analysis"],"summary":"Get Financial Profile","description":"Build a comprehensive financial profile from a user's imported transactions.\nReturns cached result if available (24h TTL), otherwise computes fresh.","operationId":"get_financial_profile_api_analysis_financial_profile__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analysis/quick-insights/{user_id}":{"get":{"tags":["Analysis"],"summary":"Get Quick Insights","description":"Return 3-5 short insight strings for the home screen cards.\nAll computed dynamically from the user's actual transaction data.","operationId":"get_quick_insights_api_analysis_quick_insights__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analysis/ai-breakdown/{user_id}":{"post":{"tags":["Analysis"],"summary":"Get Ai Breakdown","description":"Generate a personalised AI-driven financial breakdown for the onboarding flow.\nReturns cached result if available (7-day TTL) and no new goals are provided.\nOtherwise generates fresh via Claude API.","operationId":"get_ai_breakdown_api_analysis_ai_breakdown__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/AIBreakdownRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analysis/suggested-allocation/{user_id}":{"post":{"tags":["Analysis"],"summary":"Get Suggested Allocation","description":"Calculate a suggested paycheck allocation based on the user's income,\ndetected recurring bills, and financial goals.\n\nReturns: { bills, savings, investments, discretionary, weekly_budget,\n           rules, warnings }","operationId":"get_suggested_allocation_api_analysis_suggested_allocation__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/SuggestedAllocationRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analysis/refresh/{user_id}":{"post":{"tags":["Analysis"],"summary":"Refresh Caches","description":"Invalidate all cached analyses for a user, forcing fresh computation\non the next request.","operationId":"refresh_caches_api_analysis_refresh__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analysis/spending-personality/{user_id}":{"get":{"tags":["Analysis"],"summary":"Get Spending Personality","description":"Return the user's canonical spending personality, computing if stale.","operationId":"get_spending_personality_api_analysis_spending_personality__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analysis/spending":{"get":{"tags":["Analysis"],"summary":"Spending Aggregate","description":"Spending totals for a period, grouped by category and/or month.\n\nReplaces paging transactions to draw a chart. Same numbers, ~2 KB.","operationId":"spending_aggregate_api_analysis_spending_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date","title":"From"}},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date","title":"To"}},{"name":"group_by","in":"query","required":false,"schema":{"type":"string","default":"category,month","title":"Group By"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpendingAggregateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/goals":{"get":{"tags":["Goals"],"summary":"List Goals","description":"List all savings goals for the current user, plus partner's shared goals.","operationId":"list_goals_api_goals_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/app__api__goals__GoalResponse"},"type":"array","title":"Response List Goals Api Goals Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Goals"],"summary":"Create Goal","description":"Create a new savings goal.","operationId":"create_goal_api_goals_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__goals__GoalCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__goals__GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/goals/{goal_id}":{"get":{"tags":["Goals"],"summary":"Get Goal","description":"Get a specific goal by ID.","operationId":"get_goal_api_goals__goal_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Goal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__goals__GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Goals"],"summary":"Update Goal","description":"Update an existing goal.","operationId":"update_goal_api_goals__goal_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Goal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__goals__GoalUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__goals__GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Goals"],"summary":"Delete Goal","description":"Delete a goal.","operationId":"delete_goal_api_goals__goal_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Goal Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/goals/{goal_id}/contribute":{"post":{"tags":["Goals"],"summary":"Contribute To Goal","description":"Add a contribution to a savings goal.","operationId":"contribute_to_goal_api_goals__goal_id__contribute_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Goal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__goals__GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/budgets":{"get":{"tags":["Budgets"],"summary":"List Budgets","description":"List all budgets with current period spend calculated from transactions.\nAlso includes partner's shared budgets when a partnership is active.","operationId":"list_budgets_api_budgets_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BudgetResponse"},"type":"array","title":"Response List Budgets Api Budgets Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Budgets"],"summary":"Create Budget","description":"Create a spending budget for a category.","operationId":"create_budget_api_budgets_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/budgets/{budget_id}":{"put":{"tags":["Budgets"],"summary":"Update Budget","description":"Update a budget's limit or period.","operationId":"update_budget_api_budgets__budget_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"budget_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Budget Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Budgets"],"summary":"Delete Budget","description":"Delete a budget.","operationId":"delete_budget_api_budgets__budget_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"budget_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Budget Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/budgets/dismiss-alert":{"post":{"tags":["Budgets"],"summary":"Dismiss Budget Alert","description":"Dismiss a budget alert for the current period (server-side).\n\nUses server-calculated period_start to ensure the dismiss key\nalways matches the listing endpoint's key — avoids mismatches\nwhen the mobile-provided period_start is stale.","operationId":"dismiss_budget_alert_api_budgets_dismiss_alert_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DismissAlertRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/budgets/bulk-update":{"patch":{"tags":["Budgets"],"summary":"Bulk Update Budgets","description":"Update or create budgets for multiple categories in one call.\n\nFor each item: if a budget exists for the category, update its limit;\notherwise create a new monthly budget with the suggested limit.","operationId":"bulk_update_budgets_api_budgets_bulk_update_patch","requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BulkBudgetItem"},"type":"array","title":"Items"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkBudgetUpdateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/budgets/suggestions":{"get":{"tags":["Budgets"],"summary":"Get Budget Suggestions","description":"Budget suggestions from spending history. A user on BEHAVIOUR_V2 gets\nthe budget engine's (EQ-72: never a fixed cost, flexible categories only,\nsized from their own pay cycles); everyone else the v1 logic unchanged.","operationId":"get_budget_suggestions_api_budgets_suggestions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BudgetSuggestion"},"type":"array","title":"Response Get Budget Suggestions Api Budgets Suggestions Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/budgets/intelligence":{"get":{"tags":["Budgets"],"summary":"Get Budget Intelligence","description":"EQ-72: budgets with context, for a user on BEHAVIOUR_V2.\n\nstate            \"ready\" | \"not_enough_seen\" | \"v1\" (the switch is off: the\n                 app keeps reading /suggestions)\nreason           why nothing is suggested yet (not_enough_seen)\nbasis            the pay cycles the numbers come from\ncommitted        the v2 MATURE commitments: \"Committed £X/month\"\nsuggestions      max 4 flexible categories without a budget, hold / trim,\n                 a reason line built from the numbers\nbudget_checks    max 2 budgets 40%+ away from typical: set to typical or\n                 keep as a target\nfixed_cost_budgets  budgets on a never-budget category: \"this is a fixed\n                 cost, now under Committed — remove?\" (never removed here)","operationId":"get_budget_intelligence_api_budgets_intelligence_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/budgets/health-summary":{"get":{"tags":["Budgets"],"summary":"Get Budget Health","description":"Calculate overall budget health score (0-100) with grade and summary.","operationId":"get_budget_health_api_budgets_health_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetHealthSummary"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/budgets/{budget_id}/history":{"get":{"tags":["Budgets"],"summary":"Get Budget History","description":"Get last 6 months of budget history with trend analysis.","operationId":"get_budget_history_api_budgets__budget_id__history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"budget_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Budget Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/investments/summary":{"get":{"tags":["Investments — contributions and valuations"],"summary":"Get Summary","operationId":"get_summary_api_investments_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Summary Api Investments Summary Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/investments/summary/series":{"get":{"tags":["Investments — contributions and valuations"],"summary":"Get Summary Series","description":"Contributions-vs-value line for the whole portfolio (linked ticket).","operationId":"get_summary_series_api_investments_summary_series_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Summary Series Api Investments Summary Series Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/investments/accounts":{"get":{"tags":["Investments — contributions and valuations"],"summary":"List Accounts","operationId":"list_accounts_api_investments_accounts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Response List Accounts Api Investments Accounts Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Investments — contributions and valuations"],"summary":"Create Account","operationId":"create_account_api_investments_accounts_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__investments_v2__AccountCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Account Api Investments Accounts Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/investments/accounts/{account_id}":{"get":{"tags":["Investments — contributions and valuations"],"summary":"Get Account","operationId":"get_account_api_investments_accounts__account_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Account Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Account Api Investments Accounts  Account Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Investments — contributions and valuations"],"summary":"Patch Account","operationId":"patch_account_api_investments_accounts__account_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Account Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Patch Account Api Investments Accounts  Account Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Investments — contributions and valuations"],"summary":"Delete Account","operationId":"delete_account_api_investments_accounts__account_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Account Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/investments/projection":{"get":{"tags":["Investments — contributions and valuations"],"summary":"Get Portfolio Projection","description":"Three scenarios for the whole portfolio; the user's risk profile selects one.","operationId":"get_portfolio_projection_api_investments_projection_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Portfolio Projection Api Investments Projection Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/investments/accounts/{account_id}/projection":{"get":{"tags":["Investments — contributions and valuations"],"summary":"Get Account Projection","operationId":"get_account_projection_api_investments_accounts__account_id__projection_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Account Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Account Projection Api Investments Accounts  Account Id  Projection Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/investments/risk-profile":{"get":{"tags":["Investments — contributions and valuations"],"summary":"Get Risk Profile","operationId":"get_risk_profile_api_investments_risk_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Risk Profile Api Investments Risk Profile Get"}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["Investments — contributions and valuations"],"summary":"Put Risk Profile","operationId":"put_risk_profile_api_investments_risk_profile_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RiskProfileBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Put Risk Profile Api Investments Risk Profile Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/investments/suggestions":{"get":{"tags":["Investments — contributions and valuations"],"summary":"List Suggestions","operationId":"list_suggestions_api_investments_suggestions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Response List Suggestions Api Investments Suggestions Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/investments/contributions":{"post":{"tags":["Investments — contributions and valuations"],"summary":"Create Contribution","operationId":"create_contribution_api_investments_contributions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Contribution Api Investments Contributions Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/investments/contributions/{contribution_id}/confirm":{"post":{"tags":["Investments — contributions and valuations"],"summary":"Confirm Contribution","operationId":"confirm_contribution_api_investments_contributions__contribution_id__confirm_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"contribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Contribution Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ConfirmBody"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Confirm Contribution Api Investments Contributions  Contribution Id  Confirm Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/investments/contributions/{contribution_id}/reject":{"post":{"tags":["Investments — contributions and valuations"],"summary":"Reject Contribution","operationId":"reject_contribution_api_investments_contributions__contribution_id__reject_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"contribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Contribution Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Reject Contribution Api Investments Contributions  Contribution Id  Reject Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/investments/contributions/{contribution_id}":{"patch":{"tags":["Investments — contributions and valuations"],"summary":"Patch Contribution","operationId":"patch_contribution_api_investments_contributions__contribution_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"contribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Contribution Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Patch Contribution Api Investments Contributions  Contribution Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Investments — contributions and valuations"],"summary":"Delete Contribution","operationId":"delete_contribution_api_investments_contributions__contribution_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"contribution_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Contribution Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/investments/transactions/{transaction_id}/mark":{"post":{"tags":["Investments — contributions and valuations"],"summary":"Mark Transaction","description":"Idempotent on the transaction: a second mark is a 409 (the app reads\nit as \"already marked\"), never a second row or a second account.","operationId":"mark_transaction_api_investments_transactions__transaction_id__mark_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"transaction_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Transaction Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkBody"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Mark Transaction Api Investments Transactions  Transaction Id  Mark Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/investments/accounts/{account_id}/valuations":{"post":{"tags":["Investments — contributions and valuations"],"summary":"Create Valuation","operationId":"create_valuation_api_investments_accounts__account_id__valuations_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Account Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValuationBody"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Valuation Api Investments Accounts  Account Id  Valuations Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/investments/valuations/{valuation_id}":{"delete":{"tags":["Investments — contributions and valuations"],"summary":"Delete Valuation","operationId":"delete_valuation_api_investments_valuations__valuation_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"valuation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Valuation Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/investments/rules":{"get":{"tags":["Investments — contributions and valuations"],"summary":"List Rules","operationId":"list_rules_api_investments_rules_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Response List Rules Api Investments Rules Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/investments/rules/{rule_id}":{"delete":{"tags":["Investments — contributions and valuations"],"summary":"Delete Rule","operationId":"delete_rule_api_investments_rules__rule_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rule Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/investments":{"get":{"tags":["Investments"],"summary":"List Investments","description":"List all investment plans for the current user.","operationId":"list_investments_api_investments_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/InvestmentResponse"},"type":"array","title":"Response List Investments Api Investments Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Investments"],"summary":"Create Investment","description":"Create a new investment plan.","operationId":"create_investment_api_investments_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvestmentCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvestmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/investments/isa-allowance":{"get":{"tags":["Investments"],"summary":"Get Isa Allowance","description":"Remaining ISA allowance, from the investments summary (the confirmed\ncontributions into ISA / LISA accounts this tax year). Same shape as\nbefore; `plans` lists the ISA-wrapper investment accounts. The\nInvestmentPlan.isa_contributions_this_year field is 0 on every row since\nmigration 118 and is no longer read (investments ticket, follow-up 2).","operationId":"get_isa_allowance_api_investments_isa_allowance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ISAAllowanceResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/investments/{plan_id}":{"get":{"tags":["Investments"],"summary":"Get Investment","description":"Get a specific investment plan.","operationId":"get_investment_api_investments__plan_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Plan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvestmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Investments"],"summary":"Update Investment","description":"Update an investment plan.","operationId":"update_investment_api_investments__plan_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Plan Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvestmentUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvestmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Investments"],"summary":"Delete Investment","description":"Delete an investment plan.","operationId":"delete_investment_api_investments__plan_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Plan Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/investments/{plan_id}/projection":{"get":{"tags":["Investments"],"summary":"Get Projection","description":"Calculate compound growth scenarios at 4% (cautious), 7% (balanced),\nand 10% (adventurous) annual returns, showing fee impact.","operationId":"get_projection_api_investments__plan_id__projection_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"plan_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Plan Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/chat/sessions":{"get":{"tags":["Chat"],"summary":"List Sessions","description":"List all chat sessions for the authenticated user, newest first.\nIncludes last message preview and message count to avoid N+1 queries.","operationId":"list_sessions_api_chat_sessions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/app__api__chat__SessionResponse"},"type":"array","title":"Response List Sessions Api Chat Sessions Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Chat"],"summary":"Create Session","description":"Create a new chat session.","operationId":"create_session_api_chat_sessions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSessionRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__chat__SessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]},"delete":{"tags":["Chat"],"summary":"Delete All Sessions","description":"Delete all chat sessions and messages for the authenticated user.","operationId":"delete_all_sessions_api_chat_sessions_delete","responses":{"204":{"description":"Successful Response"}},"security":[{"HTTPBearer":[]}]}},"/api/chat/messages/{message_id}/feedback":{"post":{"tags":["Chat"],"summary":"Submit Feedback","description":"Submit thumbs up/down feedback on an assistant message.","operationId":"submit_feedback_api_chat_messages__message_id__feedback_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/chat/sessions/{session_id}/messages":{"post":{"tags":["Chat"],"summary":"Send Message","description":"Send a message in a chat session and receive an AI response.\nLoads the user's financial context, calls the AI, and stores both messages.","operationId":"send_message_api_chat_sessions__session_id__messages_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageRequest"}}}},"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"}}}}}},"get":{"tags":["Chat"],"summary":"Get Messages","description":"Get all messages in a chat session.","operationId":"get_messages_api_chat_sessions__session_id__messages_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MessageResponse"},"title":"Response Get Messages Api Chat Sessions  Session Id  Messages Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/chat/sessions/{session_id}/messages/stream":{"post":{"tags":["Chat"],"summary":"Send Message Stream","description":"Send a message and stream the AI response as Server-Sent Events.\n\nSSE event format:\n    data: {\"type\": \"text\", \"content\": \"chunk\"}\n    data: {\"type\": \"tool\", \"tool\": \"tool_name\"}\n    data: {\"type\": \"done\", \"message_id\": \"uuid\"}\n    data: {\"type\": \"error\", \"message\": \"error text\"}","operationId":"send_message_stream_api_chat_sessions__session_id__messages_stream_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/chat/sessions/{session_id}":{"delete":{"tags":["Chat"],"summary":"Delete Session","description":"Delete a chat session and all its messages.\n\nIdempotent: returns 200 even if session was already deleted\n(prevents double-tap race condition on mobile).","operationId":"delete_session_api_chat_sessions__session_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/chat/memories":{"get":{"tags":["Chat"],"summary":"List Memories","description":"List all active (non-superseded, non-expired) memories for the user.","operationId":"list_memories_api_chat_memories_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/MemoryResponse"},"type":"array","title":"Response List Memories Api Chat Memories Get"}}}}},"security":[{"HTTPBearer":[]}]},"delete":{"tags":["Chat"],"summary":"Delete All Memories","description":"Delete all AI memories for the current user.","operationId":"delete_all_memories_api_chat_memories_delete","responses":{"204":{"description":"Successful Response"}},"security":[{"HTTPBearer":[]}]}},"/api/chat/memories/{memory_id}":{"delete":{"tags":["Chat"],"summary":"Delete Memory","description":"Delete a single AI memory. Must belong to the current user.","operationId":"delete_memory_api_chat_memories__memory_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"memory_id","in":"path","required":true,"schema":{"type":"string","title":"Memory Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/chat/readiness":{"get":{"tags":["Chat"],"summary":"Get Readiness","description":"Readiness of Ask IQ for this user. Cheap: two narrow reads, no cache.","operationId":"get_readiness_api_chat_readiness_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/chat/usage":{"get":{"tags":["Chat"],"summary":"Get Usage","description":"Get the user's AI chat usage for today and this month.","operationId":"get_usage_api_chat_usage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/chat/execute-action":{"post":{"tags":["Chat"],"summary":"Execute Action","description":"Execute an action suggested by the AI chat (create goal, budget, challenge).","operationId":"execute_action_api_chat_execute_action_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteActionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteActionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/challenges/generate/{user_id}":{"post":{"tags":["Challenges"],"summary":"Generate Challenges","description":"Generate 2-3 personalised weekly challenges from spending data.\nReturns cached challenges if still valid (7-day TTL).","operationId":"generate_challenges_api_challenges_generate__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengesListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/challenges/detail/{challenge_id}":{"get":{"tags":["Challenges"],"summary":"Get Challenge Detail","description":"Get detailed breakdown for a challenge.\n- no_spend_day: returns which days had spending and which didn't\n- spending challenges: returns matching transactions","operationId":"get_challenge_detail_api_challenges_detail__challenge_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"challenge_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Challenge Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/challenges/history/{user_id}":{"get":{"tags":["Challenges"],"summary":"Get Challenges History","description":"Get completed and expired challenge history with stats.","operationId":"get_challenges_history_api_challenges_history__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/challenges/{user_id}":{"get":{"tags":["Challenges"],"summary":"Get Challenges","description":"Return active challenges and their progress for a user.","operationId":"get_challenges_api_challenges__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengesListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/challenges/{challenge_id}/progress":{"patch":{"tags":["Challenges"],"summary":"Patch Challenge Progress","description":"Update the current progress of a challenge.\nAutomatically marks as completed if target is met for count-based challenges,\nor if the week ends under budget for spending challenges.","operationId":"patch_challenge_progress_api_challenges__challenge_id__progress_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"challenge_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Challenge Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgressUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/challenges/{user_id}/update-progress":{"post":{"tags":["Challenges"],"summary":"Refresh Challenge Progress","description":"Recalculate challenge progress from real transaction data.\nAuto-completes or fails expired challenges. Awards XP on completion.\n\nCall this:\n- Every time the app opens\n- After every transaction sync\n- On a daily schedule","operationId":"refresh_challenge_progress_api_challenges__user_id__update_progress_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengesListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/challenges/ai-generate/{user_id}":{"post":{"tags":["Challenges"],"summary":"Generate Ai Personalised Challenges","description":"Generate AI-personalised challenges based on real spending weaknesses.\nUses Haiku to create challenges referencing specific amounts.\nPass ?force=true to regenerate even if active challenges exist.","operationId":"generate_ai_personalised_challenges_api_challenges_ai_generate__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengesListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/challenges/{user_id}/daily":{"get":{"tags":["Challenges"],"summary":"Get Daily Challenge","description":"Get today's daily micro-challenge.\nReturns an existing one if already generated today, otherwise creates a new one.\n5 XP per completion, 35 bonus XP for 7-day streak.","operationId":"get_daily_challenge_api_challenges__user_id__daily_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/challenges/{user_id}/daily/complete":{"post":{"tags":["Challenges"],"summary":"Complete Daily Challenge","description":"Mark today's daily challenge as completed. Awards 5 XP + streak bonus.\nServer-enforced: max 1 completion per user per calendar day.","operationId":"complete_daily_challenge_api_challenges__user_id__daily_complete_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/DailyCompleteRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/xp/{user_id}":{"get":{"tags":["XP"],"summary":"Get Xp","description":"Get user's current XP status, level, and recent history.","operationId":"get_xp_api_xp__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/XPResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/xp/{user_id}/award":{"post":{"tags":["XP"],"summary":"Award Xp Endpoint","description":"Award XP to a user for completing an action.","operationId":"award_xp_endpoint_api_xp__user_id__award_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwardXPRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwardXPResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/xp/{user_id}/daily-login":{"post":{"tags":["XP"],"summary":"Daily Login","description":"Check and award daily login XP. Idempotent — only awards once per day.","operationId":"daily_login_api_xp__user_id__daily_login_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DailyLoginResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/api-usage":{"get":{"tags":["Admin"],"summary":"Get Api Usage","description":"Return in-memory Anthropic API usage statistics.\n\nIncludes total calls, token counts, cost estimates (USD),\nbreakdowns by model, call type, user, and date.","operationId":"get_api_usage_api_admin_api_usage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/merchants/coverage":{"get":{"tags":["Admin"],"summary":"Get Merchant Coverage","description":"Merchant intelligence coverage statistics.\n\nReturns:\n- Total curated merchants in MerchantIntelligence\n- Total unknown merchant descriptions logged\n- Top 20 unknown merchants by occurrence_count\n- Category breakdown of curated merchants\n- Coverage ratio","operationId":"get_merchant_coverage_api_admin_merchants_coverage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/reset-iq-quota":{"post":{"tags":["Admin"],"summary":"Reset Iq Quota","description":"Reset AI usage quotas for a user.\n\n- With body ``{\"user_id\": \"...\"}`` — admin resets that user's quotas.\n- Without body — resets the current (authenticated) user's quotas.\n\nResets: tokens_used_this_month, monthly_ai_cost_usd,\ntool_actions_today, move_money_actions_today, allocation_updates_today,\nand deletes today's chat messages so the daily message limit resets.","operationId":"reset_iq_quota_api_admin_reset_iq_quota_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetIQQuotaBody","default":{}}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/seed-cancellation-urls":{"post":{"tags":["Admin"],"summary":"Seed Cancellation Urls","description":"Upsert cancellation URLs for top 50 UK subscriptions.\n\n- Existing merchants: always update cancellation_url (replaces stale URLs)\n- Missing merchants: create new record with curated metadata","operationId":"seed_cancellation_urls_api_admin_seed_cancellation_urls_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/feedback/summary":{"get":{"tags":["Admin"],"summary":"Get Feedback Summary","description":"Training data quality dashboard — feedback stats and recent negatives.","operationId":"get_feedback_summary_api_admin_feedback_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/training/stats":{"get":{"tags":["Admin"],"summary":"Get Training Stats","description":"Training data pipeline statistics (admin only).","operationId":"get_training_stats_api_admin_training_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/training/transactions/export":{"get":{"tags":["Admin"],"summary":"Export Transaction Training","description":"Export transaction training data as JSONL (admin only).","operationId":"export_transaction_training_api_admin_training_transactions_export_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Date"}},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To Date"}},{"name":"verified_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Verified Only"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/training/conversations/export":{"get":{"tags":["Admin"],"summary":"Export Conversation Training","description":"Export conversation training data as ChatML JSONL (admin only).","operationId":"export_conversation_training_api_admin_training_conversations_export_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"min_quality","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Quality"}},{"name":"from_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Date"}},{"name":"to_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To Date"}},{"name":"feedback_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Feedback Only"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/training/transactions/distilbert-export":{"get":{"tags":["Admin"],"summary":"Export Distilbert Training Data","description":"Export transaction classification training data in DistilBERT format.\n\nGenerates a complete dataset from:\n1. MerchantIntelligence match_patterns (base + augmented examples)\n2. High-confidence TransactionTrainingRecords (cross-referenced for labels)\n\nReturns JSON with texts, labels, and metadata.","operationId":"export_distilbert_training_data_api_admin_training_transactions_distilbert_export_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/training/transactions/label-stats":{"get":{"tags":["Admin"],"summary":"Get Distilbert Label Stats","description":"Label distribution statistics for DistilBERT training data.\n\nReturns per-label counts, percentages, imbalance warnings,\nand recommendations for training.","operationId":"get_distilbert_label_stats_api_admin_training_transactions_label_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/debug/bank-connections":{"get":{"tags":["Admin"],"summary":"Debug Bank Connections","description":"Diagnostic dump of all bank connections and accounts for the current user.\n\nReturns every connection (active, expired, revoked), every linked account,\ntotal transaction count, and a summary with counts by status.","operationId":"debug_bank_connections_api_admin_debug_bank_connections_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/clear-sync-cooldowns":{"post":{"tags":["Admin"],"summary":"Clear Sync Cooldowns","description":"Clear sync_cooldown_until on all of the current user's bank connections.\n\nUse this when Finexer 429 rate limits have set cooldowns that are preventing\nsyncs from running. Safe to call — worst case the next sync hits 429 again\nand sets a fresh cooldown.","operationId":"clear_sync_cooldowns_api_admin_clear_sync_cooldowns_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/fix-bank-connections":{"post":{"tags":["Admin"],"summary":"Fix Bank Connections","description":"Clean up ghost bank connections and reactivate incorrectly expired ones.\n\nSafe to run — only deactivates duplicates and resets connections that were\nincorrectly marked expired. Does NOT delete any data.\n\nSteps:\n1. Reactivate connections marked consent_expired=True whose consent_expires\n   is still in the future.\n2. For each user, deduplicate accounts by (sort_code, account_number).\n   Keep the account whose parent connection has the most recent\n   last_synced_at; deactivate the parent connections of the rest.\n3. For connections sharing the same finexer_consent_id within a user,\n   keep the most recently synced one and deactivate the rest.","operationId":"fix_bank_connections_api_admin_fix_bank_connections_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/trigger-notifications":{"post":{"tags":["Admin"],"summary":"Trigger Notifications","description":"Re-trigger specific notifications for the current user, bypassing\ntiming windows and dedup. Admin-only.","operationId":"trigger_notifications_api_admin_trigger_notifications_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"notification_types","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"},"description":"Which notifications to re-trigger","default":["daily_snapshot","forecast_update"],"title":"Notification Types"},"description":"Which notifications to re-trigger"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/backfill-transaction-types":{"post":{"tags":["Admin"],"summary":"Backfill Transaction Types","description":"Backfill transaction_type and recurring_category on existing transactions.\n\nIdempotent: skips transactions that already have transaction_type set.\n\nUses MerchantIntelligence for bill/subscription classification, plus\ncategory-based fallback for the rest. Optionally runs DistilBERT for\nrecurring transactions not matched by MI.\n\nSet dry_run=false to actually commit changes.","operationId":"backfill_transaction_types_api_admin_backfill_transaction_types_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackfillRequest","default":{"dry_run":true,"batch_size":500,"use_ml":false,"force_reclassify":false}}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/trigger":{"post":{"tags":["Admin"],"summary":"Trigger Event","description":"Simulate any app event for a specific user on demand.\nBypasses timing windows and dedup so events fire immediately.\nProtected by X-Cron-Secret header (same as cron endpoints).","operationId":"trigger_event_api_admin_trigger_post","parameters":[{"name":"X-Cron-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}},{"name":"x-cron-secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/pmi-valuations/{uprn}":{"delete":{"tags":["Admin"],"summary":"Invalidate Pmi Valuation Cache","description":"Clear a known-bad cached PMI valuation for a UPRN.\n\nThe PMI cache is global and keyed by UPRN with a 90-day staleness\nwindow, so one implausible estimate is served to every property at\nthat address until it expires. Clearing it drops affected properties\nback to the HPI estimate until PMI is next queried.","operationId":"invalidate_pmi_valuation_cache_api_admin_pmi_valuations__uprn__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"uprn","in":"path","required":true,"schema":{"type":"string","title":"Uprn"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PmiInvalidateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/push/test":{"post":{"tags":["Admin"],"summary":"Admin Send Test Push","description":"Send one test push to a user's registered device and record its ticket.","operationId":"admin_send_test_push_api_admin_push_test_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPushTestRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPushTestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/push/status":{"get":{"tags":["Admin"],"summary":"Admin Push Status","description":"Does this user hold a push token, and what did Expo say about recent sends?","operationId":"admin_push_status_api_admin_push_status_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id"}},{"name":"email","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPushStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/push/check-receipts":{"post":{"tags":["Admin"],"summary":"Admin Check Push Receipts","description":"Fetch Expo receipts now instead of waiting for the hourly cron.\n\n`min_age_seconds` overrides the 15-minute wait for one call (Expo may\nanswer sooner; an unanswered ticket is simply left unchecked).","operationId":"admin_check_push_receipts_api_admin_push_check_receipts_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"min_age_seconds","in":"query","required":false,"schema":{"type":"integer","maximum":86400,"minimum":0,"title":"Min Age Seconds"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/net-worth/{user_id}":{"get":{"tags":["Net Worth"],"summary":"Get Net Worth","description":"Get current net worth summary: totals, accounts, monthly change.","operationId":"get_net_worth_api_net_worth__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetWorthSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/net-worth/{user_id}/accounts":{"post":{"tags":["Net Worth"],"summary":"Add Account","description":"Add a manual net worth account.","operationId":"add_account_api_net_worth__user_id__accounts_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__net_worth__AccountCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__net_worth__AccountResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/net-worth/{user_id}/accounts/{account_id}":{"patch":{"tags":["Net Worth"],"summary":"Update Account","description":"Update an account's balance and other fields.","operationId":"update_account_api_net_worth__user_id__accounts__account_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"account_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Account Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__net_worth__AccountResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Net Worth"],"summary":"Delete Account","description":"Remove a net worth account.","operationId":"delete_account_api_net_worth__user_id__accounts__account_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"account_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Account Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/net-worth/{user_id}/history":{"get":{"tags":["Net Worth"],"summary":"Get History","description":"Get monthly net worth snapshots for charting.","operationId":"get_history_api_net_worth__user_id__history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/net-worth/{user_id}/snapshot":{"post":{"tags":["Net Worth"],"summary":"Create Snapshot","description":"Create a net worth snapshot from current account balances.","operationId":"create_snapshot_api_net_worth__user_id__snapshot_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnapshotResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/net-worth/{user_id}/accounts/{account_id}/overpayment":{"post":{"tags":["Net Worth"],"summary":"Calculate Overpayment","description":"Calculate impact of extra monthly overpayments on a mortgage or loan.","operationId":"calculate_overpayment_api_net_worth__user_id__accounts__account_id__overpayment_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"account_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Account Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OverpaymentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OverpaymentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/simulator/what-if/{user_id}":{"post":{"tags":["Simulator"],"summary":"What If","description":"Run what-if scenario calculations using the user's latest analysis data.\nFalls back to running a fresh analysis if none exists.","operationId":"what_if_api_simulator_what_if__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhatIfRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhatIfResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/simulator/presets/{user_id}":{"get":{"tags":["Simulator"],"summary":"Get Presets","description":"Generate pre-built scenario cards based on the user's actual spending data.\nReturns personalised suggestions they can tap to explore.","operationId":"get_presets_api_simulator_presets__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresetsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payday/preview/{user_id}":{"get":{"tags":["Payday"],"summary":"Get Payday Preview","description":"Get a payday preview with detected payday date, timeline,\nand smart suggestions based on the user's spending analysis.","operationId":"get_payday_preview_api_payday_preview__user_id__get","deprecated":true,"security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaydayPreview"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payday/rules/{user_id}":{"post":{"tags":["Payday"],"summary":"Save Payday Rules","description":"Save/update automation rules and return an updated timeline.\nRules are passed from the mobile app (stored in AsyncStorage).\nThe backend computes the timeline and remaining amounts.","operationId":"save_payday_rules_api_payday_rules__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveRulesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveRulesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payday/seed/{user_id}":{"post":{"tags":["Payday"],"summary":"Seed Payday Data","description":"Seed demo payday data. Returns pre-built rules and detected payday.\nIdempotent — safe to call multiple times.\nThe mobile app stores these rules in AsyncStorage.","operationId":"seed_payday_data_api_payday_seed__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__payday__SeedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payday/status":{"get":{"tags":["Payday"],"summary":"Get Payday Status","description":"Get detected payday info, days until next payday, and last payday date.","operationId":"get_payday_status_api_payday_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaydayStatusResponse"}}}}},"deprecated":true,"security":[{"HTTPBearer":[]}]}},"/api/payday/salary-check":{"get":{"tags":["Payday"],"summary":"Check Salary Landed","description":"Check if salary has arrived in the last 5 days.\nMatches against confirmed primary salary (income_sources) or any credit > £1000.","operationId":"check_salary_landed_api_payday_salary_check_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalaryCheckResponse"}}}}},"deprecated":true,"security":[{"HTTPBearer":[]}]}},"/api/payday/suggestion":{"get":{"tags":["Payday"],"summary":"Get Payday Suggestion","description":"Get allocation suggestion enriched with goals and budget performance.\n\nOnce the user has ACCEPTED a coach plan, the accepted plan is echoed\nback unchanged (accepted=True) for the rest of the current pay cycle —\nit is not regenerated on every fetch. A fresh suggestion is produced\nagain after the next payday has passed, so the plan updates once per\ncycle rather than every time the tab opens.","operationId":"get_payday_suggestion_api_payday_suggestion_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaydaySuggestionResponse"}}}}},"deprecated":true,"security":[{"HTTPBearer":[]}]}},"/api/payday/preferences":{"put":{"tags":["Payday"],"summary":"Update Payday Preferences","description":"Set custom allocation percentages for payday distribution.","operationId":"update_payday_preferences_api_payday_preferences_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaydayPreferencesRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaydayPreferencesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/payday/db-rules":{"get":{"tags":["Payday"],"summary":"Get Db Rules","description":"Fetch the user's payday allocation rules, with the timeline they produce.\n\nThe timeline ships with the rules so the payday screen can render on mount\nfrom this one response instead of following it with POST /rules/{user_id}.","operationId":"get_db_rules_api_payday_db_rules_get","deprecated":true,"security":[{"HTTPBearer":[]}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DBRulesResponse"}}}}}},"put":{"tags":["Payday"],"summary":"Put Db Rules","description":"Replace all payday rules for the user with the provided set.\nThis is a full overwrite — the mobile app sends the complete rule list.\n\nEQ-72 ruling 4: with ?mode=propose a virtual-pot rule whose category has\nno budget does not get one created here. It comes back as a\nbudget_proposal and the user confirms it (bulk-update). Without the mode\n(an older client) the budget is auto-created as before, never at £0.\nAn existing budget's limit is never touched by this endpoint either way.","operationId":"put_db_rules_api_payday_db_rules_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"mode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"'propose': budgets are proposed, never written (EQ-72)","title":"Mode"},"description":"'propose': budgets are proposed, never written (EQ-72)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveRulesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DBRulesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payday/db-rules/{rule_id}":{"patch":{"tags":["Payday"],"summary":"Patch Db Rule","description":"Update a single payday rule in place.\n\nThe common edits — flipping a rule on or off, nudging an amount — used to\ngo through the full PUT, which deletes and reinserts every rule the user\nhas. This touches one row.","operationId":"patch_db_rule_api_payday_db_rules__rule_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","title":"Rule Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaydayRulePatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DBRulesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payday/virtual-allocate":{"post":{"tags":["Payday"],"summary":"Virtual Allocate","description":"Process virtual pot allocations on payday.\n\nFor each rule linked to a budget category:\n1. Find the matching budget for the current user. PIS-off savings /\n   investments rules arrive without a budget row: that tracking row is\n   created. With ?mode=propose a SPENDING category with no budget is not\n   created here — the rule comes back as \"needs_budget\" and the user\n   confirms the budget from the proposal the rules PUT returned (EQ-72\n   ruling 4). An older client gets the budget created as before.\n2. Reset period_start_date to today (new period)\n3. Mark virtual_pot_funded_at = now\n4. Return confirmation\n\nmonthly_limit is never changed here. No money moves — this is purely\ntracking.","operationId":"virtual_allocate_api_payday_virtual_allocate_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"mode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"'propose': budgets are proposed, never written (EQ-72)","title":"Mode"},"description":"'propose': budgets are proposed, never written (EQ-72)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualPotRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualPotResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payday/verify-transfers":{"post":{"tags":["Payday"],"summary":"Verify Transfers","description":"Match manual payday transfers against synced transactions.\n\nWith PIS off, users move money themselves. An outbound transaction of\nthe exact amount within 14 days of payday confirms a checklist item.\nTransfer-flagged transactions are preferred over ordinary debits so a\nsame-amount card purchase doesn't steal the match; each transaction\nconfirms at most one item.","operationId":"verify_transfers_api_payday_verify_transfers_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyTransfersRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyTransfersResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/payday/apply-suggestion":{"post":{"tags":["Payday"],"summary":"Apply Suggestion","description":"Apply AI suggestion: creates allocation rules and the plan's budgets.\n\nFor each suggestion category:\n- Bills → virtual pot rule, and a 'utilities' budget\n- Savings → transfer rule (real money movement)\n- Investments → transfer rule (real money movement)\n- Discretionary → per-category budgets from spending analysis\n\nEQ-72 ruling 4 (13 Oct 2026): this endpoint used to create budgets and\nOVERWRITE the limits the user had set (the founder's eight budgets were\nrewritten on 28 Sep). Now:\n\n- ?mode=propose (the app): no budget is written. Every budget the plan\n  wants is returned in budget_proposals; the app shows them and the\n  user confirms per budget through PATCH /api/budgets/bulk-update.\n- no mode (web app, older phones): today's behaviour, except a user-set\n  limit is never overwritten or deleted — it is skipped and proposed —\n  and a £0 budget is never created. The plan still creates budgets that\n  do not exist, and may resize or remove one only while it is the\n  plan's own: created by the previous Apply and still at the limit\n  that Apply wrote (owned.budget_limits). See _BudgetWrites.","operationId":"apply_suggestion_api_payday_apply_suggestion_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"mode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"'propose': budgets are proposed, never written (EQ-72)","title":"Mode"},"description":"'propose': budgets are proposed, never written (EQ-72)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplySuggestionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplySuggestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pots/summary":{"get":{"tags":["Pots"],"summary":"Pots Summary","description":"Return 6-pot donut summary for the current month.","operationId":"pots_summary_api_pots_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PotsSummaryResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/properties/address-search":{"get":{"tags":["Properties"],"summary":"Address Search","description":"Address autocomplete → UPRN candidates via PMI. Degrades gracefully:\non any PMI failure returns search_available=false so the client falls\nback to manual postcode entry.","operationId":"address_search_api_properties_address_search_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressSearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/properties":{"get":{"tags":["Properties"],"summary":"List Properties","description":"List the user's active properties with estimated value and equity.\nReads only from our DB — no external calls.","operationId":"list_properties_api_properties_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyListResponse"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Properties"],"summary":"Create Property","description":"Register a property. Resolves the postcode via postcodes.io (once) and\nwarms the global HPI index cache for its location. Pro feature: property\ntracking requires a paid tier (existing properties keep working after a\ndowngrade — only adding new ones is gated).","operationId":"create_property_api_properties_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/properties/{property_id}/refresh-valuation":{"post":{"tags":["Properties"],"summary":"Refresh Property Valuation","description":"Explicit refresh: re-ask PMI for this property's UPRN (unless the\ncached answer is under a day old, in which case it is re-judged) and\nstore the verdict. The only user-triggered way to recompute a verdict\ninside its 30-day cache window.","operationId":"refresh_property_valuation_api_properties__property_id__refresh_valuation_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Property Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/properties/{property_id}":{"patch":{"tags":["Properties"],"summary":"Update Property","description":"Edit nickname, purchase price, mortgage balance, postcode, UPRN, or\nthe manual value override. A postcode change re-resolves the location\nand re-warms the index cache; a UPRN change attempts a PMI valuation\nwhen entitled.","operationId":"update_property_api_properties__property_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Property Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Properties"],"summary":"Delete Property","description":"Soft-delete a property (it stops counting towards net worth).","operationId":"delete_property_api_properties__property_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"property_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Property Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/consent/ai":{"get":{"tags":["Consent"],"summary":"Get Ai Consent","description":"Current AI disclosure acknowledgement status.","operationId":"get_ai_consent_api_consent_ai_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiConsentStatus"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Consent"],"summary":"Acknowledge Ai Disclosure","description":"Record the AI disclosure acknowledgement. Idempotent — repeat calls\nkeep the original acknowledgement date.","operationId":"acknowledge_ai_disclosure_api_consent_ai_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiConsentStatus"}}}}},"security":[{"HTTPBearer":[]}]},"delete":{"tags":["Consent"],"summary":"Revoke Ai Disclosure","description":"Clear the acknowledgement. Not used by the app — account deletion is\nhow a user stops AI processing. Kept for support/regulatory tooling.","operationId":"revoke_ai_disclosure_api_consent_ai_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiConsentStatus"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/review/annual/{user_id}":{"get":{"tags":["Review"],"summary":"Get Annual Review","description":"Generate a Spotify Wrapped-style annual financial review\nfrom the user's full year of transaction data.","operationId":"get_annual_review_api_review_annual__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnnualReview"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alerts/bill-changes/{user_id}":{"get":{"tags":["Alerts"],"summary":"Get Bill Changes","description":"Analyse recurring transactions and detect price increases,\ncontract renewals approaching, and duplicate charges.","operationId":"get_bill_changes_api_alerts_bill_changes__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillChangesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/referral/code":{"get":{"tags":["Referral"],"summary":"Get Referral Code","description":"Returns user's unique referral code (generates one if doesn't exist).","operationId":"get_referral_code_api_referral_code_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferralCodeResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/referral/stats":{"get":{"tags":["Referral"],"summary":"Get Referral Stats","description":"Returns referral statistics for the current user.","operationId":"get_referral_stats_api_referral_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferralStatsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/referral/redeem":{"post":{"tags":["Referral"],"summary":"Redeem Referral Code","description":"Called during onboarding when new user enters a referral code.","operationId":"redeem_referral_code_api_referral_redeem_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__referral__RedeemRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedeemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/referral/check-rewards":{"post":{"tags":["Referral"],"summary":"Check Rewards","description":"Check if any referrers should receive their reward.\nTriggered when referred user is active 7+ days.","operationId":"check_rewards_api_referral_check_rewards_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckRewardsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/referral/rewards":{"get":{"tags":["Referral"],"summary":"Get Rewards","description":"List all reward entitlements for the current user.","operationId":"get_rewards_api_referral_rewards_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/RewardItem"},"type":"array","title":"Response Get Rewards Api Referral Rewards Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/referral/{user_id}":{"get":{"tags":["Referral"],"summary":"Get Referral Dashboard","description":"Get the user's referral dashboard: code, stats, and referral list.","operationId":"get_referral_dashboard_api_referral__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferralDashboard"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/referral/{user_id}/generate":{"post":{"tags":["Referral"],"summary":"Generate Referral Code","description":"Generate a unique referral code for the user (or return existing one).","operationId":"generate_referral_code_api_referral__user_id__generate_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/referral/validate":{"post":{"tags":["Referral"],"summary":"Validate Referral Code","description":"Check if a referral code is valid. No auth required (used during registration).","operationId":"validate_referral_code_api_referral_validate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/referral/claim/{user_id}":{"post":{"tags":["Referral"],"summary":"Claim Referral","description":"Claim a referral reward after a new user signs up with a referral code.\nAwards 1 month free premium to both referrer and referred user.","operationId":"claim_referral_api_referral_claim__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__referral__ClaimRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users/{user_id}/push-token":{"post":{"tags":["Notifications"],"summary":"Save Push Token","description":"Save the device push notification token.\n\nTokens are exclusive per device: if any other user rows currently hold\nthis token (e.g. a shared test device), they are cleared first so the\ncron loop does not fan out duplicate notifications to the same phone.","operationId":"save_push_token_api_users__user_id__push_token_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushTokenRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushTokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Notifications"],"summary":"Clear Push Token","description":"Clear the user's push token (called on mobile logout).","operationId":"clear_push_token_api_users__user_id__push_token_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushTokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users/{user_id}/notification-preferences":{"get":{"tags":["Notifications"],"summary":"Get Notification Preferences","description":"Get the user's notification preferences.","operationId":"get_notification_preferences_api_users__user_id__notification_preferences_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPreferencesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Notifications"],"summary":"Update Notification Preferences","description":"Update one or more notification preferences.","operationId":"update_notification_preferences_api_users__user_id__notification_preferences_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPreferencesUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPreferencesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users/{user_id}/test-notification":{"post":{"tags":["Notifications"],"summary":"Send Test Notification","description":"Send a test push notification to the user's device.","operationId":"send_test_notification_api_users__user_id__test_notification_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/TestNotificationRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestNotificationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users/{user_id}/notification-history":{"get":{"tags":["Notifications"],"summary":"Get Notification History","description":"Return recent notification history for the user.","operationId":"get_notification_history_api_users__user_id__notification_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":30,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users/{user_id}/notifications/unread-count":{"get":{"tags":["Notifications"],"summary":"Get Unread Count","description":"Return count of unread notifications for the bell badge.","operationId":"get_unread_count_api_users__user_id__notifications_unread_count_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnreadCountResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users/{user_id}/notifications/{notification_id}/read":{"patch":{"tags":["Notifications"],"summary":"Mark Notification Read","description":"Mark a single notification as read.","operationId":"mark_notification_read_api_users__user_id__notifications__notification_id__read_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"notification_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Notification Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkReadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users/{user_id}/notifications/mark-all-read":{"post":{"tags":["Notifications"],"summary":"Mark All Notifications Read","description":"Mark all unread notifications as read.","operationId":"mark_all_notifications_read_api_users__user_id__notifications_mark_all_read_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkAllReadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payments/targets":{"get":{"tags":["Payments"],"summary":"List Targets","description":"List all allocation targets for the current user.","operationId":"list_targets_api_payments_targets_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AllocationTargetResponse"},"type":"array","title":"Response List Targets Api Payments Targets Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Payments"],"summary":"Create Target","description":"Add a new allocation target.","operationId":"create_target_api_payments_targets_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTargetRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AllocationTargetResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/payments/targets/{target_id}":{"put":{"tags":["Payments"],"summary":"Update Target","description":"Update an allocation target.","operationId":"update_target_api_payments_targets__target_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"target_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Target Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTargetRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AllocationTargetResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Payments"],"summary":"Delete Target","description":"Remove an allocation target.","operationId":"delete_target_api_payments_targets__target_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"target_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Target Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payments/initiate":{"post":{"tags":["Payments"],"summary":"Initiate Payment","description":"Initiate a single payment via Finexer PIS.\nReturns the consent_url for the user to authorise in-browser.","operationId":"initiate_payment_api_payments_initiate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitiatePaymentRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/payments/initiate-allocation":{"post":{"tags":["Payments"],"summary":"Initiate Allocation","description":"Initiate allocation payments for a payday.\nReceives a list of rules (each with target_id + amount) from the mobile client.\nLooks up the linked AllocationTarget for bank details, creates a Finexer\npayment for each, and returns consent URLs.","operationId":"initiate_allocation_api_payments_initiate_allocation_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitiateAllocationRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/PaymentResponse"},"type":"array","title":"Response Initiate Allocation Api Payments Initiate Allocation Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/payments/status/{payment_id}":{"get":{"tags":["Payments"],"summary":"Get Payment Status","description":"Check payment status from Finexer and update local record.","operationId":"get_payment_status_api_payments_status__payment_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"payment_id","in":"path","required":true,"schema":{"type":"string","title":"Payment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payments/history":{"get":{"tags":["Payments"],"summary":"Get Payment History","description":"List payment history, newest first.","operationId":"get_payment_history_api_payments_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Per Page"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payments/payday-detected":{"post":{"tags":["Payments"],"summary":"Payday Detected","description":"Called when a salary credit is detected.\nChecks if user has allocation targets set up and returns info for prompting.\nDoes NOT auto-create payments — the user must initiate.","operationId":"payday_detected_api_payments_payday_detected_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaydayDetectedResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/marketplace/products/{bucket}":{"get":{"tags":["Marketplace"],"summary":"Get Products By Bucket","description":"Return products for a given allocation bucket.","operationId":"get_products_by_bucket_api_marketplace_products__bucket__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"bucket","in":"path","required":true,"schema":{"type":"string","title":"Bucket"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Product"},"title":"Response Get Products By Bucket Api Marketplace Products  Bucket  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/marketplace/recommendations":{"get":{"tags":["Marketplace"],"summary":"Get Recommendations","description":"Return all marketplace sections with products, sorted by consumer benefit.","operationId":"get_recommendations_api_marketplace_recommendations_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/MarketplaceSection"},"type":"array","title":"Response Get Recommendations Api Marketplace Recommendations Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/marketplace/track/click":{"post":{"tags":["Marketplace"],"summary":"Track Click","description":"Log an affiliate click event for analytics and attribution.","operationId":"track_click_api_marketplace_track_click_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackClickRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackClickResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/anomalies/detect/{user_id}":{"post":{"tags":["Anomalies"],"summary":"Run Anomaly Detection","description":"Run anomaly detection on the user's transactions.\nResults are cached for 24 hours unless force=true.\nAlso persists detected anomalies to the anomalies table.","operationId":"run_anomaly_detection_api_anomalies_detect__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Force re-detection, skipping cache","default":false,"title":"Force"},"description":"Force re-detection, skipping cache"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/anomalies/{user_id}":{"get":{"tags":["Anomalies"],"summary":"List Anomalies","description":"List all anomalies for a user, optionally including dismissed ones.","operationId":"list_anomalies_api_anomalies__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"include_dismissed","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Dismissed"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnomalyListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/anomalies/{anomaly_id}/dismiss":{"post":{"tags":["Anomalies"],"summary":"Dismiss Anomaly","description":"Dismiss an anomaly so it no longer appears in the active list.","operationId":"dismiss_anomaly_api_anomalies__anomaly_id__dismiss_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"anomaly_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Anomaly Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forecast/cash-flow/{user_id}":{"get":{"tags":["Forecast"],"summary":"Get Cash Flow Forecast","description":"Generate a 30-day cash flow forecast with daily balance projections,\nrisk assessment, upcoming bills, and an AI-generated summary.\nResults are cached for 24 hours unless force=true.","operationId":"get_cash_flow_forecast_api_forecast_cash_flow__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Force re-generation, skipping cache","default":false,"title":"Force"},"description":"Force re-generation, skipping cache"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CashFlowForecastResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/recommendations/smart/{user_id}":{"get":{"tags":["Recommendations"],"summary":"Get Smart Recommendations","description":"Get AI-powered personalised recommendations based on the user's\nspending patterns. Results are cached for 7 days unless force=true.","operationId":"get_smart_recommendations_api_recommendations_smart__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Force re-generation, skipping cache","default":false,"title":"Force"},"description":"Force re-generation, skipping cache"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmartRecommendationsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/recommendations/click":{"post":{"tags":["Recommendations"],"summary":"Track Recommendation Click","description":"Track when a user clicks on a smart recommendation.","operationId":"track_recommendation_click_api_recommendations_click_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClickRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__recommendations__ClickResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/recommendations/{rec_id}/dismiss":{"post":{"tags":["Recommendations"],"summary":"Dismiss Recommendation","description":"Dismiss a recommendation. This invalidates the cached recommendations\nso the dismissed one won't re-appear until the next refresh.","operationId":"dismiss_recommendation_api_recommendations__rec_id__dismiss_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rec_id","in":"path","required":true,"schema":{"type":"string","title":"Rec Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analysis/deep/{user_id}":{"get":{"tags":["Deep Analysis"],"summary":"Get Deep Analysis","description":"Run all 10 deep analysis modules on the user's transactions.\nReturns structured data per module with AI-generated summaries.\nCached for 24 hours.","operationId":"get_deep_analysis_api_analysis_deep__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Force re-analysis, skipping cache","default":false,"title":"Force"},"description":"Force re-analysis, skipping cache"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeepAnalysisResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analysis/story/{user_id}":{"get":{"tags":["Deep Analysis"],"summary":"Get Financial Story","description":"Generate a comprehensive financial narrative (500-800 words) using Sonnet.\nWeaves together findings from all 10 analysis modules.\nCached for 24 hours. Paid tier only — free users get 403.","operationId":"get_financial_story_api_analysis_story__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Force re-generation, skipping cache","default":false,"title":"Force"},"description":"Force re-generation, skipping cache"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analysis/merchant/{user_id}/{merchant_name}":{"get":{"tags":["Deep Analysis"],"summary":"Get Merchant Context","description":"Get detailed context for a specific merchant: total spend, visit count,\naverage transaction, frequency, and trend.","operationId":"get_merchant_context_api_analysis_merchant__user_id___merchant_name__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"merchant_name","in":"path","required":true,"schema":{"type":"string","title":"Merchant Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantContext"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/briefing/weekly/{user_id}":{"get":{"tags":["Briefing"],"summary":"Get Weekly Briefing","description":"Get the latest weekly briefing. Generates one if none exists for the current week.\nFree tier users receive a 403 — weekly briefing is a paid feature.","operationId":"get_weekly_briefing_api_briefing_weekly__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeeklyBriefingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/briefing/daily-insight/{user_id}":{"get":{"tags":["Briefing"],"summary":"Get Daily Insight","description":"Get today's daily insight. Generates one if none exists for today.","operationId":"get_daily_insight_api_briefing_daily_insight__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/DailyInsightResponse"},{"type":"null"}],"title":"Response Get Daily Insight Api Briefing Daily Insight  User Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/briefing/daily-insight/{insight_id}/dismiss":{"post":{"tags":["Briefing"],"summary":"Dismiss Daily Insight","description":"Dismiss a daily insight (only the caller's own insights).","operationId":"dismiss_daily_insight_api_briefing_daily_insight__insight_id__dismiss_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"insight_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Insight Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/support/message":{"post":{"tags":["Support"],"summary":"Send Support Message","description":"Send a support message and get an AI response.","operationId":"send_support_message_api_support_message_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportMessageRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportMessageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/support/escalate":{"post":{"tags":["Support"],"summary":"Escalate To Human","description":"Escalate support conversation to human support.","operationId":"escalate_to_human_api_support_escalate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EscalateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EscalateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/support/history":{"get":{"tags":["Support"],"summary":"Get Support History","description":"Get all support chat sessions for the user.","operationId":"get_support_history_api_support_history_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/SupportHistoryResponse"},"type":"array","title":"Response Get Support History Api Support History Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/partners/invite":{"post":{"tags":["Partners"],"summary":"Send Invite","description":"Generate a 6-character invite code for partner linking. Requires premium.","operationId":"send_invite_api_partners_invite_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"email","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Fallback: invitee email as query param","title":"Email"},"description":"Fallback: invitee email as query param"}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/app__api__partners__InviteRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__partners__InviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/partners/accept":{"post":{"tags":["Partners"],"summary":"Accept Invite","description":"Accept a partner invite using a 6-character code. Requires premium.\n\nRate-limited: the 6-char code space is enumerable without throttling.","operationId":"accept_invite_api_partners_accept_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__partners__AcceptRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/partners/status":{"get":{"tags":["Partners"],"summary":"Get Status","description":"Get the current user's partnership status.","operationId":"get_status_api_partners_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/partners/end":{"delete":{"tags":["Partners"],"summary":"End Partnership","description":"End the current partnership. Both users continue independently.","operationId":"end_partnership_api_partners_end_delete","responses":{"204":{"description":"Successful Response"}},"security":[{"HTTPBearer":[]}]}},"/api/partners/combined-spending":{"get":{"tags":["Partners"],"summary":"Get Combined Spending","description":"Aggregate both partners' transactions by category for a given period.","operationId":"get_combined_spending_api_partners_combined_spending_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":7,"default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CombinedSpendingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/partners/combined-bills":{"get":{"tags":["Partners"],"summary":"Get Combined Bills","description":"List all recurring payments from both users side by side.","operationId":"get_combined_bills_api_partners_combined_bills_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CombinedBillsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/partners/goals":{"get":{"tags":["Partners"],"summary":"List Goals","description":"List all joint goals for the active partnership.","operationId":"list_goals_api_partners_goals_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/app__api__partners__GoalResponse"},"type":"array","title":"Response List Goals Api Partners Goals Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Partners"],"summary":"Create Goal","description":"Create a joint savings goal.","operationId":"create_goal_api_partners_goals_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__partners__GoalCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__partners__GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/partners/goals/{goal_id}":{"put":{"tags":["Partners"],"summary":"Update Goal","description":"Update a joint goal. Use contribute_amount to add to current_amount.","operationId":"update_goal_api_partners_goals__goal_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"goal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Goal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__partners__GoalUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__partners__GoalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/partners/split-bill":{"post":{"tags":["Partners"],"summary":"Create Split","description":"Create a new bill split between partners.","operationId":"create_split_api_partners_split_bill_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SplitBillCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SplitBillResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/partners/splits":{"get":{"tags":["Partners"],"summary":"List Splits","description":"List bill splits, optionally filtered by settled status.","operationId":"list_splits_api_partners_splits_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"settled","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Settled"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SplitBillResponse"},"title":"Response List Splits Api Partners Splits Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/partners/balance":{"get":{"tags":["Partners"],"summary":"Get Balance","description":"Net position across unsettled splits, from the caller's side.\n\nDerived from the rows on every request rather than stored, so it\ncannot drift from them: adding, settling or editing a split changes\nthe answer immediately and there is no second copy to keep in step.\n\nSettled rows are excluded — settling means \"we have squared this up\nbetween us\", so a settled split is no longer outstanding. Rows with no\nrecorded payer are excluded too and counted in `needs_payer`.","operationId":"get_balance_api_partners_balance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BalanceResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/partners/splits/{split_id}/settle":{"put":{"tags":["Partners"],"summary":"Settle Split","description":"Mark a bill split as squared up between the two of you.\n\nSettling is a bookkeeping fact, not a movement of money. earmarkIQ\ncannot make a transfer between two people's banks and cannot reliably\nobserve one, so the only thing it can honestly record is that the two\nof you consider this settled — which removes the row from the\noutstanding balance and nothing else.\n\nIt deliberately does NOT touch budget spend: _calculate_partner_spend\nsums what each person actually spent, and a transfer between partners\nis not spending by either of them. Matching a settlement to a real\nbank transfer would need partner-to-partner transfer detection and is\na separate piece of work.","operationId":"settle_split_api_partners_splits__split_id__settle_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"split_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Split Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SplitBillResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/partners/insights":{"get":{"tags":["Partners"],"summary":"Get Insights","description":"Generate AI insights about the couple's combined finances using Haiku.\n\nCached per user for 24 hours. The inputs are a 30-day spending window and\nthe recurring-payment set, neither of which moves meaningfully within a\nday, so regenerating more often spends a model call to produce the same\nfour sentences. Every other AI surface in the app already caches this way\n(weekly_briefing, deep_analysis, recurring_summary); this one did not, and\nfired a Haiku call on every mount of the partner screen.\n\nInvalidated by create/settle split and by ending the partnership.","operationId":"get_insights_api_partners_insights_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InsightsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/streaks":{"get":{"tags":["Streaks"],"summary":"Get Streaks","description":"Get the user's current streak status, daily budget, and today's spending.","operationId":"get_streaks_api_streaks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StreakStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/streaks/check":{"post":{"tags":["Streaks"],"summary":"Check Streaks","description":"Check and update the user's streak for any unchecked day(s).\nCall this on app open. Handles multi-day gaps.","operationId":"check_streaks_api_streaks_check_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StreakCheckResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/subscriptions/audit":{"get":{"tags":["Subscriptions"],"summary":"Get Subscription Audit","description":"Run a full subscription audit on the user's recurring transactions.\n\nData sources (merged):\n  1. Transactions already flagged is_recurring=True (set by analysis engine or user confirm)\n  2. Merchant grouping with 3+ occurrences (catches new patterns not yet flagged)\n  3. Latest analysis result for enrichment (next_expected_date, confidence, etc.)","operationId":"get_subscription_audit_api_subscriptions_audit_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionAuditResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/subscriptions/confirm":{"post":{"tags":["Subscriptions"],"summary":"Confirm Subscription","description":"Confirm a possible subscription as a real subscription.","operationId":"confirm_subscription_api_subscriptions_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmSubscriptionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionPreferenceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/subscriptions/dismiss":{"post":{"tags":["Subscriptions"],"summary":"Dismiss Subscription","description":"Dismiss a possible subscription as not a subscription.","operationId":"dismiss_subscription_api_subscriptions_dismiss_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DismissSubscriptionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionPreferenceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/subscriptions/confirmed":{"get":{"tags":["Subscriptions"],"summary":"Get Confirmed Subscriptions","description":"Get all confirmed subscriptions.","operationId":"get_confirmed_subscriptions_api_subscriptions_confirmed_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/SubscriptionPreferenceResponse"},"type":"array","title":"Response Get Confirmed Subscriptions Api Subscriptions Confirmed Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/subscriptions/dismissed":{"get":{"tags":["Subscriptions"],"summary":"Get Dismissed Subscriptions","description":"Get all dismissed merchants (to filter from future detections).","operationId":"get_dismissed_subscriptions_api_subscriptions_dismissed_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/SubscriptionPreferenceResponse"},"type":"array","title":"Response Get Dismissed Subscriptions Api Subscriptions Dismissed Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/bills/comparison":{"get":{"tags":["Bills"],"summary":"Get Bill Comparison","description":"Compare the user's household bills to UK averages and suggest switches.\nCovers energy, broadband, mobile, and insurance. Cached for 48 hours.","operationId":"get_bill_comparison_api_bills_comparison_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"household_type","in":"query","required":false,"schema":{"type":"string","pattern":"^(single|couple|family)$","default":"couple","title":"Household Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillComparisonResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bills/recurring-summary":{"get":{"tags":["Bills"],"summary":"Get Recurring Summary","description":"Return the 4-section Bills & Recurring summary for the caller.","operationId":"get_recurring_summary_api_bills_recurring_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecurringSummaryResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/bills/recurring-preferences":{"get":{"tags":["Bills"],"summary":"List Recurring Preferences","description":"List all recurring preferences for the current user.","operationId":"list_recurring_preferences_api_bills_recurring_preferences_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/RecurringPreferenceResponse"},"type":"array","title":"Response List Recurring Preferences Api Bills Recurring Preferences Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Bills"],"summary":"Upsert Recurring Preference","description":"Create or update a recurring preference (upsert by merchant_name).\n\nStage A rule 4: this is the ONE write behind every user edit — \"not a\nbill\" (override_type=not_recurring), an amount/frequency edit\n(bill|subscription + amount/frequency), a manual add (source=manual)\nand a section move. A real SQL upsert keyed by user + merchant, so the\nmobile outbox can replay it after being offline; every call also\nrecords a recurring_review_events row (once per client_id) and re-runs\nthe analysis so /latest, Home, Payday and budget onboarding reflect the\nedit now rather than after the next bank sync.","operationId":"upsert_recurring_preference_api_bills_recurring_preferences_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecurringPreferenceRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecurringPreferenceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/bills/recurring-preferences/merchants":{"get":{"tags":["Bills"],"summary":"Search Recurring Merchants","description":"Merchant search over the caller's own debit transactions, for \"add a\nbill the detector missed\": distinct merchants (display-normalised)\nmatching ``q``, with how often they appear, the median amount and a\ncadence guess from the median gap.","operationId":"search_recurring_merchants_api_bills_recurring_preferences_merchants_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","maxLength":100,"default":"","title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":12,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RecurringMerchantMatch"},"title":"Response Search Recurring Merchants Api Bills Recurring Preferences Merchants Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bills/recurring-preferences/{merchant_name}":{"delete":{"tags":["Bills"],"summary":"Delete Recurring Preference","description":"Remove a recurring preference (revert to automatic detection) — the\n\"undo\" in Settings. Records the training signal and re-runs the\nanalysis (Stage A rule 4). 404 when nothing is stored, so an outbox\nreplay after a successful first attempt is treated as done.","operationId":"delete_recurring_preference_api_bills_recurring_preferences__merchant_name__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"merchant_name","in":"path","required":true,"schema":{"type":"string","title":"Merchant Name"}},{"name":"client_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Client Id"}},{"name":"surface","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Surface"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/recap/monthly":{"get":{"tags":["Recap"],"summary":"Get Monthly Recap","description":"Generate or retrieve the monthly recap for the given month.","operationId":"get_monthly_recap_api_recap_monthly_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"month","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$","description":"Month in YYYY-MM format, e.g. 2026-02","title":"Month"},"description":"Month in YYYY-MM format, e.g. 2026-02"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecapResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/recap/latest":{"get":{"tags":["Recap"],"summary":"Get Latest","description":"Get the most recent monthly recap — or, before the first one exists,\n`available: false` with the fields null (a 200, never a 404).","operationId":"get_latest_api_recap_latest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecapResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/recap/list":{"get":{"tags":["Recap"],"summary":"Get Recap List","description":"List all past recaps for the user.","operationId":"get_recap_list_api_recap_list_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/RecapListItem"},"type":"array","title":"Response Get Recap List Api Recap List Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/recap/monthly-wrap":{"get":{"tags":["Recap"],"summary":"Get Monthly Wrap","description":"Get the shareable monthly financial wrap.\nTransforms the recap sections into card format for full-screen swipeable display.\nDefaults to the previous month if no month is specified.","operationId":"get_monthly_wrap_api_recap_monthly_wrap_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"month","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$","description":"Month in YYYY-MM format. Defaults to previous month.","title":"Month"},"description":"Month in YYYY-MM format. Defaults to previous month."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonthlyWrapResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/recap/monthly-wrap/viewed":{"post":{"tags":["Recap"],"summary":"Wrap Viewed","description":"Award 25 XP for viewing the monthly wrap.\nServer-enforced: max 1 XP award per user per calendar month.\nReturns 200 always, but only awards XP once per month.","operationId":"wrap_viewed_api_recap_monthly_wrap_viewed_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/recap/monthly-wrap/shared":{"post":{"tags":["Recap"],"summary":"Wrap Shared","description":"Award 50 XP for sharing the monthly wrap.","operationId":"wrap_shared_api_recap_monthly_wrap_shared_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/quizzes":{"get":{"tags":["Quizzes"],"summary":"Get Quizzes","description":"List all available quizzes with completion status.","operationId":"get_quizzes_api_quizzes_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/QuizListItem"},"type":"array","title":"Response Get Quizzes Api Quizzes Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/quizzes/{topic}":{"get":{"tags":["Quizzes"],"summary":"Get Quiz","description":"Get quiz questions for a topic.","operationId":"get_quiz_api_quizzes__topic__get","parameters":[{"name":"topic","in":"path","required":true,"schema":{"type":"string","title":"Topic"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuizQuestionsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/quizzes/{topic}/submit":{"post":{"tags":["Quizzes"],"summary":"Submit Quiz Answers","description":"Submit quiz answers and receive score with explanations.","operationId":"submit_quiz_answers_api_quizzes__topic__submit_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"topic","in":"path","required":true,"schema":{"type":"string","title":"Topic"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuizSubmitRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuizSubmitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/raise-calculator":{"post":{"tags":["Financial Tools"],"summary":"Raise Calculator","description":"Calculate the impact of a salary raise on take-home pay.","operationId":"raise_calculator_api_tools_raise_calculator_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RaiseRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RaiseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/tools/tax-tips":{"get":{"tags":["Financial Tools"],"summary":"Get Tax Tips","description":"Get personalised tax optimisation tips based on income and spending.","operationId":"get_tax_tips_api_tools_tax_tips_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxTipsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/email/unsubscribe":{"post":{"tags":["Email"],"summary":"Unsubscribe","description":"Record a marketing-email opt-out.\n\nPublic and unauthenticated by design: the earmarkiq.app/unsubscribe\npage POSTs the HMAC-signed token from the email's unsubscribe link,\nand the recipient may not have an account at all. The token is the\nauthorisation — it can only have come from an email we sent to that\naddress, so nobody can unsubscribe an address they don't receive\nmail for. Affects category=\"marketing\" sends only; transactional\nmail is never filtered.","operationId":"unsubscribe_api_email_unsubscribe_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnsubscribeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnsubscribeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/email/test":{"get":{"tags":["Email"],"summary":"Send Test Email","description":"Send a test welcome email to the authenticated user. For dev/testing only.","operationId":"send_test_email_api_email_test_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/tax/summary":{"get":{"tags":["Tax"],"summary":"Get Tax Summary","description":"Get full tax position summary for the current user.","operationId":"get_tax_summary_api_tax_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxSummaryResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/tax/pension-optimisation":{"get":{"tags":["Tax"],"summary":"Get Pension Optimisation","description":"Calculate optimal pension contributions for tax efficiency.","operationId":"get_pension_optimisation_api_tax_pension_optimisation_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PensionOptimisationResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/tax/isa-status":{"get":{"tags":["Tax"],"summary":"Get Isa Status","description":"Get ISA allowance tracking for current tax year.","operationId":"get_isa_status_api_tax_isa_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IsaStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/tax/student-loan":{"get":{"tags":["Tax"],"summary":"Get Student Loan","description":"Get student loan repayment information.","operationId":"get_student_loan_api_tax_student_loan_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentLoanResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/tax/deadlines":{"get":{"tags":["Tax"],"summary":"Get Tax Deadlines","description":"Get upcoming UK tax deadlines.","operationId":"get_tax_deadlines_api_tax_deadlines_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxDeadlinesResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/tax/tips":{"get":{"tags":["Tax"],"summary":"Get Tax Tips","description":"Get AI-generated personalised tax tips.","operationId":"get_tax_tips_api_tax_tips_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxTipsAIResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/tax/profile":{"get":{"tags":["Tax"],"summary":"Get Tax Profile","description":"Get saved tax profile for the current user.","operationId":"get_tax_profile_api_tax_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxProfileResponse"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Tax"],"summary":"Save Tax Profile","description":"Save or update tax profile for the current user.","operationId":"save_tax_profile_api_tax_profile_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxProfileRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/tax/capital-gains":{"get":{"tags":["Tax"],"summary":"Get Capital Gains","description":"Get capital gains tax position for the current tax year.","operationId":"get_capital_gains_api_tax_capital_gains_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapitalGainsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/tax/salary-sacrifice":{"get":{"tags":["Tax"],"summary":"Get Salary Sacrifice","description":"Calculate potential salary sacrifice savings.","operationId":"get_salary_sacrifice_api_tax_salary_sacrifice_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalarySacrificeResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/tax/marriage-allowance":{"get":{"tags":["Tax"],"summary":"Get Marriage Allowance","description":"Check marriage allowance eligibility.","operationId":"get_marriage_allowance_api_tax_marriage_allowance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarriageAllowanceResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/exports/spending":{"post":{"tags":["Exports"],"summary":"Export Spending","description":"Generate spending export (CSV or PDF).","operationId":"export_spending_api_exports_spending_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpendingExportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/exports/subscriptions":{"post":{"tags":["Exports"],"summary":"Export Subscriptions","description":"Generate subscription audit PDF.","operationId":"export_subscriptions_api_exports_subscriptions_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/exports/tax-summary":{"post":{"tags":["Exports"],"summary":"Export Tax Summary","description":"Generate tax summary CSV.","operationId":"export_tax_summary_api_exports_tax_summary_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxExportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/exports/ai-report":{"post":{"tags":["Exports"],"summary":"Generate Ai Report","description":"Generate AI-powered financial report. Requires premium subscription.","operationId":"generate_ai_report_api_exports_ai_report_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AIReportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/exports/ai-report/status":{"get":{"tags":["Exports"],"summary":"Get Ai Report Status","description":"Get AI report generation status for current month.","operationId":"get_ai_report_status_api_exports_ai_report_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AIReportStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/exports/ai-report/custom":{"post":{"tags":["Exports"],"summary":"Generate Custom Ai Report","description":"Generate a custom AI report based on user's specific prompt. Requires premium.","operationId":"generate_custom_ai_report_api_exports_ai_report_custom_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomAIReportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/exports/monthly-report/send":{"post":{"tags":["Exports"],"summary":"Send Monthly Report To User","description":"Email the monthly report to the current user.","operationId":"send_monthly_report_to_user_api_exports_monthly_report_send_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailReportResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/exports/monthly-report/send-all":{"post":{"tags":["Exports"],"summary":"Send Monthly Reports To All","description":"Send monthly reports to all users with email reports enabled. Admin only.","operationId":"send_monthly_reports_to_all_api_exports_monthly_report_send_all_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailReportResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/exports/my-data":{"get":{"tags":["Exports"],"summary":"Export My Data","description":"GDPR data export — download all personal data as JSON.\nReturns every piece of data Earmark holds for the authenticated user.","operationId":"export_my_data_api_exports_my_data_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/exports/{export_id}/download":{"get":{"tags":["Exports"],"summary":"Download Export","description":"Download a generated export file.","operationId":"download_export_api_exports__export_id__download_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"export_id","in":"path","required":true,"schema":{"type":"string","title":"Export Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/exports/test":{"get":{"tags":["Exports"],"summary":"Test Export","description":"Generate a simple test PDF to verify export pipeline works.","operationId":"test_export_api_exports_test_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/openbanking/connect":{"post":{"tags":["openbanking"],"summary":"Connect Bank","description":"Start the Finexer Open Banking flow.\nCreates a Finexer customer if needed, then creates a consent_link.\nReturns the consent_url to redirect the user to.\n\nAccepts an optional ``return_url`` in the JSON body so the mobile client\ncan provide the deep-link URL that matches the current environment (Expo Go\nvs standalone build).\n\nMulti-bank connections require premium.","operationId":"connect_bank_api_openbanking_connect_post","requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/app__api__openbanking__ConnectRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__openbanking__ConnectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/openbanking/status/{consent_link_id}":{"get":{"tags":["openbanking"],"summary":"Check Status","description":"Check consent_link status. If authorized, fetch and store bank accounts.\n\nA closed attempt answers from our own row, without Finexer: a link\nwhose consent was cancelled / failed / expired stays \"new\" or \"sent\" at\nFinexer for ever, so polling it could never tell the app the attempt\nwas over — 26 minutes of it on 26 Sep (EQ-55). The webhook closes the\nPendingBankAuth (finexer_webhooks._close_pending_auth); this is where\nthe app learns of it.","operationId":"check_status_api_openbanking_status__consent_link_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"consent_link_id","in":"path","required":true,"schema":{"type":"string","title":"Consent Link Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/openbanking/refresh-balances":{"post":{"tags":["openbanking"],"summary":"Refresh Balances","description":"Refresh Account.balance for all active connections via Finexer's\nbalance GET — separate from the 1/hour sync budget, so balance changes\ncan reach the app in seconds instead of waiting for the next sync.\nPer-account failures are skipped, never fatal.","operationId":"refresh_balances_api_openbanking_refresh_balances_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BalanceRefreshResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/openbanking/sync/{user_id}":{"post":{"tags":["openbanking"],"summary":"Sync Transactions","description":"Sync all Finexer bank connections for a user:\n- Trigger sync on each bank account\n- Poll until idle (max 30s)\n- Fetch and store all transactions\n\nIMPORTANT: This endpoint must NEVER call finexer.create_customer() or\nfinexer.create_consent_link(). It only operates on existing BankConnection\nrecords using their stored finexer_bank_account_id.","operationId":"sync_transactions_api_openbanking_sync__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__openbanking__SyncResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/openbanking/accounts/{user_id}":{"get":{"tags":["openbanking"],"summary":"List Accounts","description":"Return all bank connections for the user (including expired for re-auth prompt).\n\nIncludes provider=\"demo\" (seeded review/beta accounts) so the demo bank\nappears in Settings → Connected Banks like a real connection.","operationId":"list_accounts_api_openbanking_accounts__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BankConnectionResponse"},"title":"Response List Accounts Api Openbanking Accounts  User Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/openbanking/disconnect/{connection_id}":{"delete":{"tags":["openbanking"],"summary":"Disconnect Bank","description":"Disconnect a bank connection (set status to revoked).\nOptionally revokes the consent on Finexer side.\nDoes NOT delete the user's transactions.","operationId":"disconnect_bank_api_openbanking_disconnect__connection_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"connection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Connection Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisconnectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/openbanking/remove-account/{connection_id}":{"post":{"tags":["openbanking"],"summary":"Remove Account","description":"Remove ONE account at a bank without disconnecting the bank.\n\nParks the connection as status \"removed\" (the pot pattern): no future\nsyncs, hidden from every surface, transactions retained but hidden.\nThe Finexer consent is NOT touched — sibling accounts on the same\nconsent keep syncing, and the account can be restored without a new\nbank authorisation.\n\nIf this is the LAST account at the bank, the consent is deliberately\nleft live and idle rather than revoked: revoking it would make the\npromised no-re-auth restore impossible, and ending the bank's access\nis exactly what the separate \"Disconnect this bank\" action is for.\nThe consent still expires on its own 90-day clock if never used.","operationId":"remove_account_api_openbanking_remove_account__connection_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"connection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Connection Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveAccountResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/openbanking/restore-account/{connection_id}":{"post":{"tags":["openbanking"],"summary":"Restore Account","description":"Restore a removed account. The consent was never revoked, so while it\nis still live this needs no new bank authorisation: the connection\ngoes straight back to \"active\" and a sync is attempted. If the\nconsent lapsed while the account was removed, the connection is\nsurfaced as \"expired\" so the normal reconnect flow takes over.","operationId":"restore_account_api_openbanking_restore_account__connection_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"connection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Connection Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreAccountResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/openbanking/add-bank/{user_id}":{"post":{"tags":["openbanking"],"summary":"Add Bank","description":"For users who want to add another bank after initial onboarding.\nCreates a new consent_link for the user's existing Finexer customer.","operationId":"add_bank_api_openbanking_add_bank__user_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/app__api__openbanking__ConnectRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddBankResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/openbanking/complete-add-bank":{"post":{"tags":["openbanking"],"summary":"Complete Add Bank","description":"Complete the add-bank flow after the user returns from Finexer auth.\nChecks consent status with retries, creates BankConnection + Account\nrecords, triggers sync, and returns the new connection details.\n\nIdempotency: per-consent_link_id lock prevents multi-browser race.\nIf a connection was already created for this consent_link_id, returns it.","operationId":"complete_add_bank_api_openbanking_complete_add_bank_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteAddBankRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteAddBankResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/openbanking/has-connections/{user_id}":{"get":{"tags":["openbanking"],"summary":"Has Connections","description":"Check if a user has any active bank connections.\n\nIncludes provider=\"demo\" (seeded review/beta accounts): a demo\nconnection has real transactions and a balance, so surfaces keyed on\nhas_connections — the Getting Started checklist, home hero, sync\nhints — must treat it as connected. Sync paths are unaffected: they\nfilter provider=\"finexer\" themselves.","operationId":"has_connections_api_openbanking_has_connections__user_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/openbanking/retry-import/{connection_id}":{"post":{"tags":["openbanking"],"summary":"Retry Import","description":"The user's Retry for a first import that gave up (import_failed) or is\nstill waiting (awaiting_data). Resets the backoff schedule — attempts,\nnext-attempt time, the empty-probe clock — and runs ONE probe at once\nthrough the lease-guarded pull. 3 per 10 minutes per user.","operationId":"retry_import_api_openbanking_retry_import__connection_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"connection_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Connection Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryImportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/openbanking/reclassify":{"post":{"tags":["openbanking"],"summary":"Reclassify Transactions","description":"Re-classify all 'general' transactions for the current user using the\nsmart classifier + AI fallback. Uses existing merchant_name and\ndescription fields. Does not re-fetch from the bank.\n\nPipeline:\n1. Rule-based: merchant lookup → keyword → finexer type\n2. AI batch: remaining 'general' transactions sent to Claude Haiku\n\nNever touches a row the user (or their adviser) set — a row the user\ndeliberately set to \"general\" stays general — and never stores an AI\nanswer as the user's merchant rule (11 Oct 2026: it did, and those\nrules then outranked everything; scripts/classification/mark_ai_rules.py\nmarks the ones already written).","operationId":"reclassify_transactions_api_openbanking_reclassify_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReclassifyResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/income/detected":{"get":{"tags":["Income"],"summary":"Detect Income","description":"Auto-detect income sources from the user's transaction history.\nGroups recurring credits by description, filters out transfers/refunds,\nand assigns confidence scores.","operationId":"detect_income_api_income_detected_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/income/confirm":{"post":{"tags":["Income"],"summary":"Confirm Income Sources","description":"Save user-confirmed income sources. Replaces any existing confirmed sources.\n\nStores at most one primary. Shipped App Store clients pre-tick every\nsalary candidate, so a payload with several flagged rows is normal\ntraffic, not an error: the highest amount keeps the flag (payload order\non a tie), the rest are stored un-flagged, and the response shows what\nwas stored.","operationId":"confirm_income_sources_api_income_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncomeConfirmRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/income/sources":{"get":{"tags":["Income"],"summary":"List Income Sources","description":"List all confirmed income sources for the current user.","operationId":"list_income_sources_api_income_sources_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/income/sources/{source_id}":{"put":{"tags":["Income"],"summary":"Update Income Source","description":"Update a specific income source.","operationId":"update_income_source_api_income_sources__source_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"source_id","in":"path","required":true,"schema":{"type":"string","title":"Source Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncomeSourceUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Income"],"summary":"Delete Income Source","description":"Delete a specific income source.","operationId":"delete_income_source_api_income_sources__source_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"source_id","in":"path","required":true,"schema":{"type":"string","title":"Source Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/achievements/all":{"get":{"tags":["Achievements"],"summary":"Get All Badges","description":"Get all badges with lock/unlock status for the current user.","operationId":"get_all_badges_api_achievements_all_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/achievements":{"get":{"tags":["Achievements"],"summary":"Get Unlocked Badges","description":"Get only unlocked badges for the current user.","operationId":"get_unlocked_badges_api_achievements_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/achievements/check":{"post":{"tags":["Achievements"],"summary":"Check Badges","description":"Trigger a badge check and return any newly unlocked badges.\nRate-limited to 1 call per user per 60 seconds.","operationId":"check_badges_api_achievements_check_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sync/background":{"post":{"tags":["Background Sync"],"summary":"Background Sync","description":"Lightweight background sync. Called periodically by mobile background fetch.\nRate limited to 1 call per 10 minutes per user.\nPer-user lock prevents concurrent sync from foreground burst (~40 simultaneous requests).","operationId":"background_sync_api_sync_background_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackgroundSyncResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/transactions/{transaction_id}/override":{"post":{"tags":["Transaction Overrides"],"summary":"Create Or Update Override","description":"Create or update an override for a transaction.","operationId":"create_or_update_override_api_transactions__transaction_id__override_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"transaction_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Transaction Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OverrideCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OverrideResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Transaction Overrides"],"summary":"Delete Override","description":"Put the transaction back to its automatic state.\n\nTwo different things are called an \"override\" by the clients, and\nthis route undoes both (17 Oct 2026: the web's \"reset category to\nautomatic\" called it and got 404 twice):\n\n- the TransactionOverride row (notes, excluded_from_budgets,\n  is_reimbursable, reimbursed, splits) — deleted if present;\n- the category the user (or their adviser) set on the row\n  (`category_changed_by`), which the category endpoint writes to the\n  transaction itself and, for scope \"merchant\", to a\n  MerchantCategoryOverride rule. The rule for this merchant is deleted,\n  the row is re-classified by the automatic path (the v2 category order\n  for a CLASSIFY_V2 user, the rules classifier otherwise) and\n  `category_changed_by` is cleared.\n\n404 only when the transaction is not this user's. Nothing to undo is\na 200 with both flags false, so a double tap is harmless.","operationId":"delete_override_api_transactions__transaction_id__override_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"transaction_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Transaction Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OverrideDeleteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/transactions/reimbursables":{"get":{"tags":["Transaction Overrides"],"summary":"List Reimbursables","description":"List all unreimbursed reimbursable transactions with running total.","operationId":"list_reimbursables_api_transactions_reimbursables_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReimbursablesResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/iq/dashboard":{"get":{"tags":["IQ Dashboard"],"summary":"Get Iq Dashboard","description":"Get the full IQ Dashboard data for the authenticated user.","operationId":"get_iq_dashboard_api_iq_dashboard_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"refresh","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Refresh"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IQDashboardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/switching/opportunities":{"get":{"tags":["Switching"],"summary":"Get Opportunities","description":"Return all active switching opportunities for the current user.","operationId":"get_opportunities_api_switching_opportunities_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunitiesResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/switching/opportunities/{opportunity_id}":{"get":{"tags":["Switching"],"summary":"Get Opportunity","description":"Get a single opportunity by ID.","operationId":"get_opportunity_api_switching_opportunities__opportunity_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"opportunity_id","in":"path","required":true,"schema":{"type":"string","title":"Opportunity Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/switching/opportunities/{opportunity_id}/shown":{"post":{"tags":["Switching"],"summary":"Mark Shown","description":"Mark an opportunity as shown to the user.","operationId":"mark_shown_api_switching_opportunities__opportunity_id__shown_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"opportunity_id","in":"path","required":true,"schema":{"type":"string","title":"Opportunity Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/switching/opportunities/{opportunity_id}/click":{"post":{"tags":["Switching"],"summary":"Track Click","description":"Track an affiliate click and return the enriched URL.","operationId":"track_click_api_switching_opportunities__opportunity_id__click_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"opportunity_id","in":"path","required":true,"schema":{"type":"string","title":"Opportunity Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__switching__ClickResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/switching/opportunities/{opportunity_id}/confirm":{"post":{"tags":["Switching"],"summary":"Confirm Switch","description":"Confirm a switch (or that user stayed) and award XP.","operationId":"confirm_switch_api_switching_opportunities__opportunity_id__confirm_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"opportunity_id","in":"path","required":true,"schema":{"type":"string","title":"Opportunity Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/switching/opportunities/{opportunity_id}/dismiss":{"post":{"tags":["Switching"],"summary":"Dismiss Opportunity","description":"Dismiss or snooze an opportunity.","operationId":"dismiss_opportunity_api_switching_opportunities__opportunity_id__dismiss_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"opportunity_id","in":"path","required":true,"schema":{"type":"string","title":"Opportunity Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DismissRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/switching/savings":{"get":{"tags":["Switching"],"summary":"Get Savings","description":"Total confirmed savings breakdown + running cumulative counter.","operationId":"get_savings_api_switching_savings_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavingsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/market-data/pending":{"get":{"tags":["Admin - Market Data"],"summary":"List Pending","description":"List all pending market data entries for admin review.","operationId":"list_pending_api_admin_market_data_pending_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status: pending, approved, rejected","default":"pending","title":"Status"},"description":"Filter by status: pending, approved, rejected"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PendingEntryResponse"},"title":"Response List Pending Api Admin Market Data Pending Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/market-data/{entry_id}/approve":{"post":{"tags":["Admin - Market Data"],"summary":"Approve Entry","description":"Approve a pending entry, moving it to market_data_live.","operationId":"approve_entry_api_admin_market_data__entry_id__approve_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","title":"Entry Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiveEntryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/market-data/{entry_id}/reject":{"post":{"tags":["Admin - Market Data"],"summary":"Reject Entry","description":"Reject a pending entry with optional reason.","operationId":"reject_entry_api_admin_market_data__entry_id__reject_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","title":"Entry Id"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectRequest","default":{}}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/market-data/live":{"get":{"tags":["Admin - Market Data"],"summary":"List Live","description":"List current live market data entries (non-superseded).","operationId":"list_live_api_admin_market_data_live_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/LiveEntryResponse"},"type":"array","title":"Response List Live Api Admin Market Data Live Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/market-data/trigger-scan":{"post":{"tags":["Admin - Market Data"],"summary":"Trigger Scan","description":"Manually trigger a market scan outside of cron schedule.","operationId":"trigger_scan_api_admin_market_data_trigger_scan_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/home/dashboard":{"get":{"tags":["Home"],"summary":"Get Dashboard","description":"Aggregated home screen data — single request replaces 14+ individual calls.\n\nCache states:\n  - fresh   → returned as-is                    (`x-cache: HIT`)\n  - stale   → returned now, rebuilt behind      (`x-cache: STALE`)\n  - missing → rebuilt synchronously             (`x-cache: MISS`)\n\nPass ?refresh=true to force a synchronous rebuild.","operationId":"get_dashboard_api_home_dashboard_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"refresh","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Refresh"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/webhooks/finexer":{"post":{"tags":["webhooks"],"summary":"Finexer Webhook","description":"Receive and process Finexer webhook events.\n\nSecurity: HMAC-SHA256 signature verification.\nIdempotency: WebhookEvent table prevents duplicate processing.","operationId":"finexer_webhook_api_webhooks_finexer_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/webhooks/revenuecat":{"post":{"tags":["webhooks"],"summary":"Revenuecat Webhook","description":"Receive and process RevenueCat webhook events.\n\nAlways returns 200 to prevent RevenueCat retries (we handle errors internally).\nAuth is verified before any processing.","operationId":"revenuecat_webhook_api_webhooks_revenuecat_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/cron/run-notifications":{"post":{"tags":["cron"],"summary":"Run Notifications","description":"Run the notification cron job. Called hourly by Railway cron.\nProtected by X-Cron-Secret header.\nAccepts both X-Cron-Secret and x-cron-secret header casing.\n\nCron command (scripts/cron_run_notifications.sh):\n    curl -sS --fail --max-time 600 -X POST \"$API_URL/api/cron/run-notifications\" -H \"X-Cron-Secret: $CRON_SECRET\"","operationId":"run_notifications_api_cron_run_notifications_post","parameters":[{"name":"X-Cron-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}},{"name":"x-cron-secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CronResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cron/sync-all":{"post":{"tags":["cron"],"summary":"Sync All Connections","description":"Sync all bank connections for all active users.\nCan be called independently of the notification cron.\nProtected by X-Cron-Secret header.","operationId":"sync_all_connections_api_cron_sync_all_post","parameters":[{"name":"X-Cron-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}},{"name":"x-cron-secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncCronResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cron/run-market-scan":{"post":{"tags":["cron"],"summary":"Run Market Scan","description":"Run a market price scan independently of the main cron.\nProtected by X-Cron-Secret header (same as notifications cron).","operationId":"run_market_scan_api_cron_run_market_scan_post","parameters":[{"name":"X-Cron-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}},{"name":"x-cron-secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketScanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cron/snapshot-net-worth":{"post":{"tags":["cron"],"summary":"Snapshot Net Worth","description":"Snapshot net worth for all users with net worth accounts.\nDesigned for daily 03:00 UTC Railway cron (D6).\nProtected by X-Cron-Secret header.","operationId":"snapshot_net_worth_api_cron_snapshot_net_worth_post","parameters":[{"name":"X-Cron-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}},{"name":"x-cron-secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NetWorthSnapshotResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cron/refresh-hpi":{"post":{"tags":["cron"],"summary":"Refresh Hpi","description":"Refresh cached UKHPI house price indices for all active properties.\nDesigned as a monthly Railway cron; safe to run daily (no-ops when no\nnew month is published). Protected by X-Cron-Secret header.","operationId":"refresh_hpi_api_cron_refresh_hpi_post","parameters":[{"name":"X-Cron-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}},{"name":"x-cron-secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HpiRefreshResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cron/refresh-pmi":{"post":{"tags":["cron"],"summary":"Refresh Pmi","description":"Refresh cached PMI property valuations (quarterly staleness — safe to\nschedule monthly; no-ops when nothing is stale). Stops cleanly on the\nmonthly credit cap. Protected by X-Cron-Secret header.","operationId":"refresh_pmi_api_cron_refresh_pmi_post","parameters":[{"name":"X-Cron-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}},{"name":"x-cron-secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PmiRefreshResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cron/complete-pending-banks":{"post":{"tags":["cron"],"summary":"Complete Pending Banks","description":"Retry pending bank auths that Finexer hasn't completed yet.\nDesigned for every-1-minute Railway cron.\nProtected by X-Cron-Secret header.","operationId":"complete_pending_banks_api_cron_complete_pending_banks_post","parameters":[{"name":"X-Cron-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}},{"name":"x-cron-secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PendingBankAuthResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cron/behaviour-shadow":{"post":{"tags":["cron"],"summary":"Behaviour Shadow","description":"Behaviour model v2: a manual backfill over every user (18 Oct 2026).\nThe model runs inline after every sync (app/services/behaviour_trigger),\nso nothing depends on this; it is for a backfill on demand. One backfill\nat a time (the job lease; no minimum interval — a second call while one\nruns answers \"skipped\" with reason \"held\"); each user goes through the\nper-user lease the inline runs take. With BEHAVIOUR_V2_SHADOW and\nBEHAVIOUR_V2 off and no per-user override it answers \"skipped\",\nreason \"flags_off\".","operationId":"behaviour_shadow_api_cron_behaviour_shadow_post","parameters":[{"name":"X-Cron-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}},{"name":"x-cron-secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BehaviourShadowResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cron/label-merchants":{"post":{"tags":["cron"],"summary":"Label Merchants","description":"Label the merchant keys the sync queued (CLASSIFY_V2), in batches of 50,\nunder MERCHANT_LABEL_DAILY_CAP_GBP (app/services/classification/\nlabel_job.py). Its own cron entry, outside the sync loop; leased.\nProtected by X-Cron-Secret header.","operationId":"label_merchants_api_cron_label_merchants_post","parameters":[{"name":"X-Cron-Secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}},{"name":"x-cron-secret","in":"header","required":false,"schema":{"type":"string","title":"X-Cron-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabelMerchantsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/billing/checkout":{"post":{"tags":["Billing"],"summary":"Create Checkout","description":"Start a Stripe Checkout for the chosen tier.","operationId":"create_checkout_api_billing_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__stripe_billing__SessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/billing/portal":{"post":{"tags":["Billing"],"summary":"Create Portal","description":"Billing portal for managing or cancelling a web subscription.","operationId":"create_portal_api_billing_portal_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__stripe_billing__SessionResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/billing/entitlement":{"get":{"tags":["Billing"],"summary":"Get Entitlement","description":"Effective tier and which source granted it, so Settings can point the\nuser at the right place to manage or cancel.","operationId":"get_entitlement_api_billing_entitlement_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntitlementResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/stripe/webhooks":{"post":{"tags":["Stripe Webhooks"],"summary":"Stripe Webhooks","operationId":"stripe_webhooks_api_stripe_webhooks_post","parameters":[{"name":"Stripe-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/access-log":{"get":{"tags":["Access Log"],"summary":"Access Log","description":"Everyone who has accessed your data, newest first.","operationId":"access_log_api_access_log_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(adviser|assistant)$"},{"type":"null"}],"description":"Limit to one kind of accessor. Omit for everything.","title":"Source"},"description":"Limit to one kind of accessor. Omit for everything."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Per Page"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessLogResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/access-log/advisers":{"get":{"tags":["Access Log"],"summary":"Adviser Access Log","description":"Adviser firms that have accessed your data, newest first.","operationId":"adviser_access_log_api_access_log_advisers_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Per Page"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessLogResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/access-log/assistants":{"get":{"tags":["Access Log"],"summary":"Assistant Access Log","description":"Assistant connections that have read your data, newest first.","operationId":"assistant_access_log_api_access_log_assistants_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Per Page"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessLogResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/mcp-tokens":{"get":{"tags":["earmarkIQ Context"],"summary":"List Tokens","description":"List this user's Context connections (PATs and OAuth connector grants).\nAuth codes are internal plumbing and are not shown.","operationId":"list_tokens_api_mcp_tokens_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenListResponse"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["earmarkIQ Context"],"summary":"Create Pat","description":"Create a personal access token. The raw token is returned once and\nstored only as a hash — copy it now.","operationId":"create_pat_api_mcp_tokens_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenCreated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/mcp-tokens/scopes":{"get":{"tags":["earmarkIQ Context"],"summary":"Scope Catalogue","description":"Every permission a connection can hold, with the words to describe it.\n\nThe list endpoint returns `covers` only for scopes a connection already\nhas, which is enough to display a grant but not to edit one — an app\noffering to ADD a permission has to name one the user does not yet\nhold. Rather than let each client keep its own copy of the wording and\ndrift from the browser consent screen the same user reads during OAuth,\nthey all read it from scopes.py through here.\n\nNot gated on Pro: this is the copy that explains what Context is, and\nthe people most in need of it are the ones who have not subscribed yet.","operationId":"scope_catalogue_api_mcp_tokens_scopes_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScopeCatalogue"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/mcp-tokens/{token_id}/scopes":{"patch":{"tags":["earmarkIQ Context"],"summary":"Update Token Scopes","description":"Narrow (or re-grant) what one connection can read, without severing it.\n\nThis is what makes a scope independently revocable: the user can take\naway transactions and keep subscriptions, rather than having to kill\nthe whole connection. Applies on the connection's very next call —\ntools read the scope from the token row, not from the bearer claims.\n\nNarrowing a legacy context:read grant to an explicit set is the\nsupported way for an existing user to move off all-access.","operationId":"update_token_scopes_api_mcp_tokens__token_id__scopes_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"token_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Token Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScopeUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenItem"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/mcp-tokens/{token_id}":{"delete":{"tags":["earmarkIQ Context"],"summary":"Revoke Token","description":"Revoke a token/connection. Takes effect on the next MCP call.","operationId":"revoke_token_api_mcp_tokens__token_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"token_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Token Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/.well-known/oauth-authorization-server":{"get":{"tags":["MCP Discovery"],"summary":"Oauth Authorization Server","operationId":"oauth_authorization_server__well_known_oauth_authorization_server_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Oauth Authorization Server  Well Known Oauth Authorization Server Get"}}}}}}},"/.well-known/oauth-authorization-server/mcp":{"get":{"tags":["MCP Discovery"],"summary":"Oauth Authorization Server Mcp","operationId":"oauth_authorization_server_mcp__well_known_oauth_authorization_server_mcp_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Oauth Authorization Server Mcp  Well Known Oauth Authorization Server Mcp Get"}}}}}}},"/.well-known/oauth-protected-resource/mcp":{"get":{"tags":["MCP Discovery"],"summary":"Oauth Protected Resource Mcp","operationId":"oauth_protected_resource_mcp__well_known_oauth_protected_resource_mcp_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Oauth Protected Resource Mcp  Well Known Oauth Protected Resource Mcp Get"}}}}}}},"/.well-known/oauth-protected-resource":{"get":{"tags":["MCP Discovery"],"summary":"Oauth Protected Resource","operationId":"oauth_protected_resource__well_known_oauth_protected_resource_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Oauth Protected Resource  Well Known Oauth Protected Resource Get"}}}}}}},"/api/internal/metrics":{"get":{"tags":["internal"],"summary":"Get Metrics","description":"Aggregate metrics as JSON. Cached in-process for ~5 minutes.\n\nReal users only by default; ?include_test=true adds flagged test\naccounts back in.","operationId":"get_metrics_api_internal_metrics_get","parameters":[{"name":"include_test","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Test"}},{"name":"X-Admin-Secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Metrics Api Internal Metrics Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/metrics/page":{"get":{"tags":["internal"],"summary":"Get Metrics Page","description":"Self-contained server-rendered HTML view of the same aggregates.","operationId":"get_metrics_page_api_internal_metrics_page_get","parameters":[{"name":"include_test","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Test"}},{"name":"X-Admin-Secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/users":{"get":{"tags":["internal"],"summary":"Admin User List","operationId":"admin_user_list_api_internal_users_get","parameters":[{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"created","title":"Sort"}},{"name":"direction","in":"query","required":false,"schema":{"type":"string","default":"desc","title":"Direction"}},{"name":"view","in":"query","required":false,"schema":{"type":"string","default":"all","title":"View"}},{"name":"tier","in":"query","required":false,"schema":{"type":"string","default":"all","title":"Tier"}},{"name":"conn","in":"query","required":false,"schema":{"type":"string","default":"all","title":"Conn"}},{"name":"X-Admin-Secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/users/{user_id}/test-flag":{"post":{"tags":["internal"],"summary":"Admin Toggle Test Flag","operationId":"admin_toggle_test_flag_api_internal_users__user_id__test_flag_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"X-Admin-Secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/users/{user_id}/delete":{"post":{"tags":["internal"],"summary":"Admin Delete User","description":"Irreversible. Requires the account email typed as confirmation, runs\nthe SAME deletion path as a user's own deletion (bulk cascade + Finexer\nconsent revocation), and records the action in admin_actions.","operationId":"admin_delete_user_api_internal_users__user_id__delete_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"X-Admin-Secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Secret"}}],"requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_admin_delete_user_api_internal_users__user_id__delete_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users/me/onboarding-profile":{"get":{"tags":["Onboarding profile"],"summary":"Get Onboarding Profile","operationId":"get_onboarding_profile_api_users_me_onboarding_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingProfileResponse"}}}}},"security":[{"HTTPBearer":[]}]},"patch":{"tags":["Onboarding profile"],"summary":"Update Onboarding Profile","operationId":"update_onboarding_profile_api_users_me_onboarding_profile_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingProfile"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/users/me/acquisition":{"get":{"tags":["Acquisition"],"summary":"Get Acquisition","operationId":"get_acquisition_api_users_me_acquisition_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcquisitionResponse"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Acquisition"],"summary":"Post Acquisition","operationId":"post_acquisition_api_users_me_acquisition_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcquisitionAnswer"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcquisitionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/users/me/pay":{"get":{"tags":["Pay schedule"],"summary":"Get Pay Schedule","operationId":"get_pay_schedule_api_users_me_pay_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayScheduleResponse"}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["Pay schedule"],"summary":"Confirm Pay Schedule","description":"Confirm (or edit) the pay schedule. Fields that don't belong to the\nchosen cadence are cleared, so switching cadence leaves nothing stale.","operationId":"confirm_pay_schedule_api_users_me_pay_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayScheduleBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayScheduleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/payday/cycle":{"get":{"tags":["Payday cycle"],"summary":"Get Cycle","operationId":"get_cycle_api_payday_cycle_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Cycle Api Payday Cycle Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/payday/cycle/version":{"get":{"tags":["Payday cycle"],"summary":"Get Cycle Version","operationId":"get_cycle_version_api_payday_cycle_version_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Cycle Version Api Payday Cycle Version Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/payday/split":{"put":{"tags":["Payday cycle"],"summary":"Put Split","operationId":"put_split_api_payday_split_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SplitBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Put Split Api Payday Split Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/payday/ticks":{"post":{"tags":["Payday cycle"],"summary":"Post Tick","operationId":"post_tick_api_payday_ticks_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TickBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Post Tick Api Payday Ticks Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/codes/redeem":{"post":{"tags":["Access codes"],"summary":"Redeem Code","description":"Apply a code to the signed-in account.\n\nResponse: outcome (granted | link_required | discount_handoff |\nattributed), policy, tier, starts_at, ends_at, link_required,\nalready_subscribed, attribution_recorded, checkout (discounts: the\nhand-off into the existing Stripe checkout — see\naccess_codes.discount_handoff).\n\nRefusals are 4xx with detail={\"code\", \"message\"}; code is stable:\ninvalid 404 · expired 410 · used 409 · revoked 410 · cap_reached 409 ·\nalready_redeemed 409 · paused 423 · adviser_unavailable 503 · web_only 403.","operationId":"redeem_code_api_codes_redeem_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__codes__RedeemRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/attribution/claim":{"post":{"tags":["Access codes"],"summary":"Claim Attribution","description":"Record who sent this user, within 7 days of sign-up. Never unlocks\nanything, whatever the batch's policy is — the app ignores the body on\npurpose (Apple 3.1.1).\n\n200 {\"outcome\": \"recorded\" | \"already_recorded\"}\n404 invalid_code · 410 window_closed · 429 rate limited","operationId":"claim_attribution_api_attribution_claim_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__api__codes__ClaimRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/":{"get":{"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"Readiness","operationId":"readiness_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/health":{"get":{"summary":"Health Check","description":"Health check endpoint for monitoring.","operationId":"health_check_api_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/health/db":{"get":{"summary":"Db Pool Health","description":"Database connection pool status for monitoring.\n\nUse this to detect pool exhaustion:\ncurl https://api.earmarkiq.app/api/health/db","operationId":"db_pool_health_api_health_db_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/health/ml":{"get":{"summary":"Health Ml","description":"earmarkIQ local classifier health check with full label inventory.","operationId":"health_ml_api_health_ml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AIBreakdownRequest":{"properties":{"goals":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Goals"}},"type":"object","title":"AIBreakdownRequest"},"AIReportRequest":{"properties":{"period":{"type":"string","title":"Period"}},"type":"object","required":["period"],"title":"AIReportRequest"},"AIReportStatusResponse":{"properties":{"reports_generated_this_month":{"type":"integer","title":"Reports Generated This Month"},"limit":{"type":"integer","title":"Limit"},"available":{"type":"boolean","title":"Available"}},"type":"object","required":["reports_generated_this_month","limit","available"],"title":"AIReportStatusResponse"},"AccessEvent":{"properties":{"id":{"type":"string","title":"Id"},"source":{"type":"string","title":"Source"},"actor":{"type":"string","title":"Actor"},"description":{"type":"string","title":"Description"},"data":{"type":"string","title":"Data"},"kind":{"type":"string","title":"Kind"},"at":{"type":"string","format":"date-time","title":"At"}},"type":"object","required":["id","source","actor","description","data","kind","at"],"title":"AccessEvent"},"AccessLogResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AccessEvent"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","pages"],"title":"AccessLogResponse"},"AccountPatch":{"properties":{"provider":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Provider"},"wrapper_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wrapper Type"},"display_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Display Name"},"is_pension":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Pension"},"link_networth_account_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Link Networth Account Id"},"create_networth":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Create Networth"},"planned_monthly":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Planned Monthly"}},"type":"object","title":"AccountPatch"},"AccountUpdate":{"properties":{"balance":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Balance"},"account_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Name"},"institution":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Institution"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"interest_rate":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Interest Rate"},"monthly_payment":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Monthly Payment"},"property_value":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Property Value"},"remaining_term_months":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Remaining Term Months"},"rate_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rate Type"},"fixed_rate_end_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fixed Rate End Date"}},"type":"object","title":"AccountUpdate"},"AcquisitionAnswer":{"properties":{"source":{"type":"string","enum":["app_store_search","google_search","friend_or_family","reddit","tiktok_or_instagram","youtube","linkedin","financial_adviser","email_from_earmarkiq","other","skipped"],"title":"Source"},"detail":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Detail"}},"additionalProperties":false,"type":"object","required":["source"],"title":"AcquisitionAnswer","description":"The request body: one option key and, for \"other\", what they typed."},"AcquisitionResponse":{"properties":{"source":{"anyOf":[{"type":"string","enum":["app_store_search","google_search","friend_or_family","reddit","tiktok_or_instagram","youtube","linkedin","financial_adviser","email_from_earmarkiq","other","skipped"]},{"type":"null"}],"title":"Source"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"recorded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Recorded At"},"recorded":{"type":"boolean","title":"Recorded","default":false}},"type":"object","title":"AcquisitionResponse","description":"`recorded` is true only on the call that stored the answer."},"AddBankResponse":{"properties":{"consent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consent Id"},"consent_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consent Url"},"consent_link_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consent Link Id"}},"type":"object","title":"AddBankResponse"},"AddressCandidate":{"properties":{"uprn":{"type":"string","title":"Uprn"},"address":{"type":"string","title":"Address"},"postcode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Postcode"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence"}},"type":"object","required":["uprn","address","postcode","confidence"],"title":"AddressCandidate"},"AddressSearchResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/AddressCandidate"},"type":"array","title":"Results"},"search_available":{"type":"boolean","title":"Search Available"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["results","search_available"],"title":"AddressSearchResponse"},"AdminPushStatusResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"email":{"type":"string","title":"Email"},"has_token":{"type":"boolean","title":"Has Token"},"push_token_prefix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Push Token Prefix"},"last_active":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Active"},"recent_tickets":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Recent Tickets"}},"type":"object","required":["user_id","email","has_token","push_token_prefix","last_active","recent_tickets"],"title":"AdminPushStatusResponse"},"AdminPushTestRequest":{"properties":{"user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"}},"type":"object","title":"AdminPushTestRequest"},"AdminPushTestResponse":{"properties":{"sent":{"type":"boolean","title":"Sent"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"ticket_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ticket Id"},"push_token_prefix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Push Token Prefix"}},"type":"object","required":["sent"],"title":"AdminPushTestResponse"},"AdviserLoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"AdviserLoginRequest"},"AdviserNetWorthResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"client_label":{"type":"string","title":"Client Label"},"total_assets":{"type":"number","title":"Total Assets"},"total_debts":{"type":"number","title":"Total Debts"},"net_worth":{"type":"number","title":"Net Worth"},"property_estimated_value":{"type":"number","title":"Property Estimated Value"},"property_mortgage_balance":{"type":"number","title":"Property Mortgage Balance"},"property_equity":{"type":"number","title":"Property Equity"},"breakdown":{"items":{"$ref":"#/components/schemas/AssetClassBreakdown"},"type":"array","title":"Breakdown"},"history":{"items":{"$ref":"#/components/schemas/NetWorthHistoryPoint"},"type":"array","title":"History"}},"type":"object","required":["user_id","client_label","total_assets","total_debts","net_worth","property_estimated_value","property_mortgage_balance","property_equity","breakdown","history"],"title":"AdviserNetWorthResponse"},"AdviserRefreshRequest":{"properties":{"refresh_token":{"type":"string","title":"Refresh Token"}},"type":"object","required":["refresh_token"],"title":"AdviserRefreshRequest"},"AdviserTokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"type":"string","title":"Refresh Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"firm_id":{"type":"string","title":"Firm Id"},"firm_name":{"type":"string","title":"Firm Name"}},"type":"object","required":["access_token","refresh_token","firm_id","firm_name"],"title":"AdviserTokenResponse"},"AiConsentStatus":{"properties":{"acknowledged":{"type":"boolean","title":"Acknowledged"},"acknowledged_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acknowledged At"},"disclosure_version":{"type":"string","title":"Disclosure Version","default":"2026-08"}},"type":"object","required":["acknowledged","acknowledged_at"],"title":"AiConsentStatus"},"AllocationBreakdown":{"properties":{"category":{"type":"string","title":"Category"},"amount":{"type":"number","title":"Amount"},"percentage":{"type":"number","title":"Percentage"}},"type":"object","required":["category","amount","percentage"],"title":"AllocationBreakdown"},"AllocationRuleItem":{"properties":{"target_id":{"type":"string","title":"Target Id"},"amount":{"type":"number","exclusiveMinimum":0.0,"title":"Amount"},"label":{"type":"string","title":"Label"}},"type":"object","required":["target_id","amount","label"],"title":"AllocationRuleItem","description":"A rule with target_id and amount, sent from the mobile client."},"AllocationSuggestion":{"properties":{"save_percent":{"type":"integer","title":"Save Percent"},"invest_percent":{"type":"integer","title":"Invest Percent"},"spend_percent":{"type":"integer","title":"Spend Percent"},"save_monthly":{"type":"number","title":"Save Monthly"},"invest_monthly":{"type":"number","title":"Invest Monthly"},"spend_monthly":{"type":"number","title":"Spend Monthly"}},"type":"object","required":["save_percent","invest_percent","spend_percent","save_monthly","invest_monthly","spend_monthly"],"title":"AllocationSuggestion"},"AllocationTargetResponse":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"},"sort_code":{"type":"string","title":"Sort Code"},"account_number":{"type":"string","title":"Account Number"},"holder_name":{"type":"string","title":"Holder Name"},"is_active":{"type":"boolean","title":"Is Active"},"goal_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Goal Id"},"goal_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Goal Name"},"allocation_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Allocation Type"},"allocation_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Allocation Value"}},"type":"object","required":["id","label","sort_code","account_number","holder_name","is_active"],"title":"AllocationTargetResponse"},"AlternativeSuggestion":{"properties":{"suggestion":{"type":"string","title":"Suggestion"},"saving_hint":{"type":"string","title":"Saving Hint"}},"type":"object","required":["suggestion","saving_hint"],"title":"AlternativeSuggestion"},"AnalysisResponse":{"properties":{"id":{"type":"string","title":"Id"},"run_at":{"type":"string","title":"Run At"},"period_start":{"type":"string","title":"Period Start"},"period_end":{"type":"string","title":"Period End"},"version":{"type":"integer","title":"Version"},"result":{"additionalProperties":true,"type":"object","title":"Result"}},"type":"object","required":["id","run_at","period_start","period_end","version","result"],"title":"AnalysisResponse"},"AnalysisStatusResponse":{"properties":{"has_transactions":{"type":"boolean","title":"Has Transactions"},"transaction_count":{"type":"integer","title":"Transaction Count"},"has_analysis":{"type":"boolean","title":"Has Analysis"},"dashboard_ready":{"type":"boolean","title":"Dashboard Ready","default":false},"backfill":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Backfill"}},"type":"object","required":["has_transactions","transaction_count","has_analysis"],"title":"AnalysisStatusResponse"},"AnnualReview":{"properties":{"year":{"type":"integer","title":"Year"},"total_earned":{"type":"number","title":"Total Earned"},"total_spent":{"type":"number","title":"Total Spent"},"total_saved":{"type":"number","title":"Total Saved"},"savings_rate":{"type":"number","title":"Savings Rate"},"top_categories":{"items":{"$ref":"#/components/schemas/CategoryStat"},"type":"array","title":"Top Categories"},"top_merchants":{"items":{"$ref":"#/components/schemas/MerchantStat"},"type":"array","title":"Top Merchants"},"biggest_spend_day":{"$ref":"#/components/schemas/BiggestSpendDay"},"cheapest_month":{"$ref":"#/components/schemas/MonthStat"},"most_expensive_month":{"$ref":"#/components/schemas/MonthStat"},"spending_personality":{"type":"string","title":"Spending Personality"},"personality_description":{"type":"string","title":"Personality Description"},"personality_emoji":{"type":"string","title":"Personality Emoji"},"monthly_trend":{"items":{"$ref":"#/components/schemas/app__api__review__MonthlyTrend"},"type":"array","title":"Monthly Trend"},"fun_facts":{"items":{"type":"string"},"type":"array","title":"Fun Facts"},"year_in_numbers":{"$ref":"#/components/schemas/YearInNumbers"},"goals_progress":{"items":{"$ref":"#/components/schemas/GoalProgress"},"type":"array","title":"Goals Progress"},"next_year_potential":{"$ref":"#/components/schemas/NextYearPotential"}},"type":"object","required":["year","total_earned","total_spent","total_saved","savings_rate","top_categories","top_merchants","biggest_spend_day","cheapest_month","most_expensive_month","spending_personality","personality_description","personality_emoji","monthly_trend","fun_facts","year_in_numbers","goals_progress","next_year_potential"],"title":"AnnualReview"},"AnnualReviewPack":{"properties":{"user_id":{"type":"string","title":"User Id"},"client_label":{"type":"string","title":"Client Label"},"firm_name":{"type":"string","title":"Firm Name"},"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"as_of":{"type":"string","format":"date","title":"As Of"},"current_period":{"$ref":"#/components/schemas/PeriodOut"},"prior_period":{"anyOf":[{"$ref":"#/components/schemas/PeriodOut"},{"type":"null"}]},"comparison_available":{"type":"boolean","title":"Comparison Available"},"comparison_note":{"type":"string","title":"Comparison Note"},"history_starts":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"History Starts"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"omitted":{"items":{"$ref":"#/components/schemas/OmittedSection"},"type":"array","title":"Omitted"},"total_expenditure":{"$ref":"#/components/schemas/MovementOut"},"by_pot":{"items":{"$ref":"#/components/schemas/MovementOut"},"type":"array","title":"By Pot"},"by_category":{"items":{"$ref":"#/components/schemas/MovementOut"},"type":"array","title":"By Category"},"largest_movements_absolute":{"items":{"$ref":"#/components/schemas/MovementOut"},"type":"array","title":"Largest Movements Absolute"},"largest_movements_percentage":{"items":{"$ref":"#/components/schemas/MovementOut"},"type":"array","title":"Largest Movements Percentage"},"monthly":{"items":{"$ref":"#/components/schemas/MonthPointOut"},"type":"array","title":"Monthly"},"income":{"anyOf":[{"$ref":"#/components/schemas/IncomeOut"},{"type":"null"}]},"net_worth":{"anyOf":[{"$ref":"#/components/schemas/NetWorthOut"},{"type":"null"}]},"property_position":{"anyOf":[{"$ref":"#/components/schemas/PropertyOut"},{"type":"null"}]},"commentary":{"items":{"$ref":"#/components/schemas/CommentaryOut"},"type":"array","title":"Commentary"},"sources":{"items":{"$ref":"#/components/schemas/SourceNoteOut"},"type":"array","title":"Sources"},"disclaimer":{"type":"string","title":"Disclaimer"}},"type":"object","required":["user_id","client_label","firm_name","generated_at","as_of","current_period","prior_period","comparison_available","comparison_note","history_starts","scopes","omitted","total_expenditure","by_pot","by_category","largest_movements_absolute","largest_movements_percentage","monthly","income","net_worth","property_position","commentary","sources","disclaimer"],"title":"AnnualReviewPack"},"AnnualSavingInfo":{"properties":{"monthly_total":{"type":"number","title":"Monthly Total"},"annual_equivalent":{"type":"number","title":"Annual Equivalent"},"saving":{"type":"number","title":"Saving"}},"type":"object","required":["monthly_total","annual_equivalent","saving"],"title":"AnnualSavingInfo"},"AnomalyListResponse":{"properties":{"anomalies":{"items":{"$ref":"#/components/schemas/AnomalyResponse"},"type":"array","title":"Anomalies"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["anomalies","total"],"title":"AnomalyListResponse"},"AnomalyResponse":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"type":{"type":"string","title":"Type"},"severity":{"type":"string","title":"Severity"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"ai_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Description"},"data":{"additionalProperties":true,"type":"object","title":"Data"},"dismissed":{"type":"boolean","title":"Dismissed","default":false},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["type","severity","title","description","data"],"title":"AnomalyResponse"},"AppleAuthRequest":{"properties":{"identity_token":{"type":"string","title":"Identity Token"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref"}},"type":"object","required":["identity_token"],"title":"AppleAuthRequest"},"ApplySuggestionRequest":{"properties":{"allocations":{"items":{"$ref":"#/components/schemas/SuggestionAllocation"},"type":"array","title":"Allocations"},"summary":{"anyOf":[{"type":"string","maxLength":1200},{"type":"null"}],"title":"Summary"},"goal_split":{"items":{"$ref":"#/components/schemas/GoalSplit"},"type":"array","maxItems":25,"title":"Goal Split"},"buffer":{"anyOf":[{"$ref":"#/components/schemas/CoachBuffer"},{"type":"null"}]}},"type":"object","required":["allocations"],"title":"ApplySuggestionRequest"},"ApplySuggestionResponse":{"properties":{"budgets_created":{"type":"integer","title":"Budgets Created"},"budgets_updated":{"type":"integer","title":"Budgets Updated"},"rules_created":{"type":"integer","title":"Rules Created"},"rules_updated":{"type":"integer","title":"Rules Updated","default":0},"budgets_removed":{"type":"integer","title":"Budgets Removed","default":0},"rules_deactivated":{"type":"integer","title":"Rules Deactivated","default":0},"budgets_proposed":{"type":"integer","title":"Budgets Proposed","default":0},"budget_proposals":{"items":{"$ref":"#/components/schemas/BudgetProposal"},"type":"array","title":"Budget Proposals","default":[]},"items":{"items":{"$ref":"#/components/schemas/CreatedItem"},"type":"array","title":"Items"},"rules":{"items":{"$ref":"#/components/schemas/PaydayRule"},"type":"array","title":"Rules"}},"type":"object","required":["budgets_created","budgets_updated","rules_created","items","rules"],"title":"ApplySuggestionResponse"},"AssetClassBreakdown":{"properties":{"asset_class":{"type":"string","title":"Asset Class"},"total":{"type":"number","title":"Total"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["asset_class","total","count"],"title":"AssetClassBreakdown"},"AuditRecommendation":{"properties":{"type":{"type":"string","title":"Type"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"items":{"items":{"$ref":"#/components/schemas/RecommendationEntry"},"type":"array","title":"Items"},"saving_monthly":{"type":"number","title":"Saving Monthly"},"saving_annual":{"type":"number","title":"Saving Annual"}},"type":"object","required":["type","title","description","items","saving_monthly","saving_annual"],"title":"AuditRecommendation"},"AuditRow":{"properties":{"id":{"type":"string","title":"Id"},"adviser_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Adviser Id"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"action":{"type":"string","title":"Action"},"detail":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Detail"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","adviser_id","user_id","action","detail","created_at"],"title":"AuditRow"},"AwardXPRequest":{"properties":{"action":{"type":"string","title":"Action"},"xp":{"type":"integer","title":"Xp"},"description":{"type":"string","title":"Description"}},"type":"object","required":["action","xp","description"],"title":"AwardXPRequest"},"AwardXPResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"action":{"type":"string","title":"Action"},"xp_awarded":{"type":"integer","title":"Xp Awarded"},"total_xp":{"type":"integer","title":"Total Xp"},"level":{"type":"integer","title":"Level"},"level_name":{"type":"string","title":"Level Name"},"leveled_up":{"type":"boolean","title":"Leveled Up"},"old_level":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Old Level"},"new_level":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"New Level"}},"type":"object","required":["user_id","action","xp_awarded","total_xp","level","level_name","leveled_up"],"title":"AwardXPResponse"},"BackfillRequest":{"properties":{"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"dry_run":{"type":"boolean","title":"Dry Run","default":true},"batch_size":{"type":"integer","title":"Batch Size","default":500},"use_ml":{"type":"boolean","title":"Use Ml","default":false},"force_reclassify":{"type":"boolean","title":"Force Reclassify","default":false}},"type":"object","title":"BackfillRequest"},"BackgroundSyncResponse":{"properties":{"synced_transactions":{"type":"integer","title":"Synced Transactions"},"challenges_updated":{"type":"integer","title":"Challenges Updated"},"notifications_sent":{"type":"integer","title":"Notifications Sent"},"last_synced_at":{"type":"string","title":"Last Synced At"},"connections_rate_limited":{"type":"integer","title":"Connections Rate Limited","default":0},"connections_consent_expired":{"type":"integer","title":"Connections Consent Expired","default":0},"connections_failed":{"type":"integer","title":"Connections Failed","default":0}},"type":"object","required":["synced_transactions","challenges_updated","notifications_sent","last_synced_at"],"title":"BackgroundSyncResponse"},"BalanceRefreshAccount":{"properties":{"account_id":{"type":"string","title":"Account Id"},"balance":{"type":"number","title":"Balance"},"balance_updated":{"type":"string","title":"Balance Updated"}},"type":"object","required":["account_id","balance","balance_updated"],"title":"BalanceRefreshAccount"},"BalanceRefreshResponse":{"properties":{"refreshed":{"type":"integer","title":"Refreshed"},"skipped":{"type":"integer","title":"Skipped"},"accounts":{"items":{"$ref":"#/components/schemas/BalanceRefreshAccount"},"type":"array","title":"Accounts","default":[]}},"type":"object","required":["refreshed","skipped"],"title":"BalanceRefreshResponse"},"BalanceResponse":{"properties":{"net":{"type":"number","title":"Net"},"direction":{"type":"string","title":"Direction"},"unsettled_count":{"type":"integer","title":"Unsettled Count"},"needs_payer":{"type":"integer","title":"Needs Payer"}},"type":"object","required":["net","direction","unsettled_count","needs_payer"],"title":"BalanceResponse","description":"Who owes whom, over unsettled splits with a known payer."},"BankConnectionResponse":{"properties":{"id":{"type":"string","title":"Id"},"institution_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Institution Id"},"institution_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Institution Name"},"institution_logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Institution Logo Url"},"account_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Name"},"account_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Type"},"sort_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort Code"},"account_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Number"},"currency":{"type":"string","title":"Currency"},"balance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Balance"},"balance_updated":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Balance Updated"},"status":{"type":"string","title":"Status"},"last_synced_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Synced At"},"connected_at":{"type":"string","title":"Connected At"},"consent_expired":{"type":"boolean","title":"Consent Expired","default":false},"consent_expires":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consent Expires"},"consent_last_authorised_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consent Last Authorised At"},"last_sync_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Sync Status"},"last_sync_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Sync Error"},"last_sync_attempted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Sync Attempted At"},"stale":{"type":"boolean","title":"Stale","default":false}},"type":"object","required":["id","institution_id","institution_name","institution_logo_url","account_name","account_type","sort_code","account_number","currency","status","last_synced_at","connected_at"],"title":"BankConnectionResponse"},"BehaviourShadowResponse":{"properties":{"status":{"type":"string","title":"Status"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"users":{"type":"integer","title":"Users","default":0},"runs":{"type":"integer","title":"Runs","default":0},"skipped":{"type":"integer","title":"Skipped","default":0},"errors":{"type":"integer","title":"Errors","default":0},"timing":{"additionalProperties":true,"type":"object","title":"Timing","default":{}}},"type":"object","required":["status"],"title":"BehaviourShadowResponse"},"BiggestSpendDay":{"properties":{"date":{"type":"string","title":"Date"},"amount":{"type":"number","title":"Amount"},"description":{"type":"string","title":"Description"}},"type":"object","required":["date","amount","description"],"title":"BiggestSpendDay"},"BillChangesResponse":{"properties":{"price_increases":{"items":{"$ref":"#/components/schemas/PriceIncrease"},"type":"array","title":"Price Increases"},"contract_renewals":{"items":{"$ref":"#/components/schemas/ContractRenewal"},"type":"array","title":"Contract Renewals"},"duplicate_charges":{"items":{"$ref":"#/components/schemas/DuplicateCharge"},"type":"array","title":"Duplicate Charges"},"total_potential_saving_monthly":{"type":"number","title":"Total Potential Saving Monthly"},"total_potential_saving_annual":{"type":"number","title":"Total Potential Saving Annual"},"notifications_pending":{"type":"boolean","title":"Notifications Pending"}},"type":"object","required":["price_increases","contract_renewals","duplicate_charges","total_potential_saving_monthly","total_potential_saving_annual","notifications_pending"],"title":"BillChangesResponse"},"BillComparison":{"properties":{"category":{"type":"string","title":"Category"},"label":{"type":"string","title":"Label"},"icon":{"type":"string","title":"Icon"},"merchant":{"type":"string","title":"Merchant"},"current_cost":{"type":"number","title":"Current Cost"},"average_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Average Cost"},"best_deal_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Best Deal Cost"},"potential_saving_monthly":{"type":"number","title":"Potential Saving Monthly"},"potential_saving_annual":{"type":"number","title":"Potential Saving Annual"},"potential_saving_vs_best_monthly":{"type":"number","title":"Potential Saving Vs Best Monthly"},"potential_saving_vs_best_annual":{"type":"number","title":"Potential Saving Vs Best Annual"},"confidence":{"type":"string","title":"Confidence"},"status":{"type":"string","title":"Status"},"can_switch":{"type":"boolean","title":"Can Switch"},"description":{"type":"string","title":"Description"},"switch_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Switch Description"},"affiliate_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Affiliate Category"},"affiliate_url":{"type":"string","title":"Affiliate Url","default":""},"renewal_info":{"anyOf":[{"$ref":"#/components/schemas/RenewalInfo"},{"type":"null"}]},"sim_only_opportunity":{"type":"boolean","title":"Sim Only Opportunity","default":false},"months_active":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Months Active"},"last_charge_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Charge Date"},"next_expected_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Expected Date"},"interval_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Interval Type"},"has_benchmark":{"type":"boolean","title":"Has Benchmark","default":true}},"type":"object","required":["category","label","icon","merchant","current_cost","potential_saving_monthly","potential_saving_annual","potential_saving_vs_best_monthly","potential_saving_vs_best_annual","confidence","status","can_switch","description"],"title":"BillComparison"},"BillComparisonResponse":{},"BillItem":{"properties":{"merchant":{"type":"string","title":"Merchant"},"category":{"type":"string","title":"Category"},"label":{"type":"string","title":"Label"},"icon":{"type":"string","title":"Icon"},"monthly_cost":{"type":"number","title":"Monthly Cost"},"split_pct":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Split Pct"},"full_monthly_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Full Monthly Cost"},"interval_type":{"type":"string","title":"Interval Type"},"months_active":{"type":"integer","title":"Months Active"},"last_charge_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Charge Date"},"next_expected_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Expected Date"},"has_benchmark":{"type":"boolean","title":"Has Benchmark","default":false},"average_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Average Cost"},"best_deal_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Best Deal Cost"},"potential_saving_annual":{"type":"number","title":"Potential Saving Annual","default":0},"can_switch":{"type":"boolean","title":"Can Switch","default":false},"switch_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Switch Description"},"affiliate_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Affiliate Category"},"charge_count":{"type":"integer","title":"Charge Count","default":0},"user_overridden":{"type":"boolean","title":"User Overridden","default":false},"confirmation_status":{"type":"string","title":"Confirmation Status","default":"confirmed"}},"type":"object","required":["merchant","category","label","icon","monthly_cost","interval_type","months_active"],"title":"BillItem"},"BillSplitRequest":{"properties":{"merchant_name":{"type":"string","title":"Merchant Name"},"user_share_pct":{"type":"integer","title":"User Share Pct"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"}},"type":"object","required":["merchant_name","user_share_pct"],"title":"BillSplitRequest"},"BillSplitResponse":{"properties":{"id":{"type":"string","title":"Id"},"merchant_name":{"type":"string","title":"Merchant Name"},"user_share_pct":{"type":"integer","title":"User Share Pct"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"}},"type":"object","required":["id","merchant_name","user_share_pct","label","created_at","updated_at"],"title":"BillSplitResponse"},"BillSplitUpdateRequest":{"properties":{"user_share_pct":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Share Pct"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"}},"type":"object","title":"BillSplitUpdateRequest"},"BillsDetail":{"properties":{"count":{"type":"integer","title":"Count"},"fixed_bills":{"type":"number","title":"Fixed Bills"}},"type":"object","required":["count","fixed_bills"],"title":"BillsDetail","description":"What the plan's Bills is made of (26 Sep 2026): how many recurring\nbills and subscriptions the coach counted, and the total it fixed."},"Body_admin_delete_user_api_internal_users__user_id__delete_post":{"properties":{"confirm_email":{"type":"string","title":"Confirm Email","default":""}},"type":"object","title":"Body_admin_delete_user_api_internal_users__user_id__delete_post"},"BriefingSectionResponse":{"properties":{"title":{"type":"string","title":"Title"},"content":{"type":"string","title":"Content"}},"type":"object","required":["title","content"],"title":"BriefingSectionResponse"},"BudgetBreakdown":{"properties":{"budget_id":{"type":"string","title":"Budget Id"},"category":{"type":"string","title":"Category"},"spent":{"type":"number","title":"Spent"},"limit":{"type":"number","title":"Limit"},"utilisation_pct":{"type":"number","title":"Utilisation Pct"},"rollover_amount":{"type":"number","title":"Rollover Amount","default":0.0},"effective_limit":{"type":"number","title":"Effective Limit"},"period":{"type":"string","title":"Period"},"status":{"type":"string","title":"Status"}},"type":"object","required":["budget_id","category","spent","limit","utilisation_pct","effective_limit","period","status"],"title":"BudgetBreakdown"},"BudgetCreate":{"properties":{"client_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Client Id"},"category":{"type":"string","title":"Category"},"monthly_limit":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Monthly Limit"},"period":{"$ref":"#/components/schemas/BudgetPeriod","default":"monthly"},"period_start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Period Start Date"},"period_end_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Period End Date"},"shared_with_partner":{"type":"boolean","title":"Shared With Partner","default":false},"rollover_enabled":{"type":"boolean","title":"Rollover Enabled","default":false},"budget_type":{"type":"string","title":"Budget Type","default":"fixed"},"income_percentage":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Income Percentage"},"payday_cycle":{"type":"boolean","title":"Payday Cycle","default":false}},"type":"object","required":["category","monthly_limit"],"title":"BudgetCreate"},"BudgetHealthSummary":{"properties":{"health_score":{"type":"integer","title":"Health Score"},"grade":{"type":"string","title":"Grade"},"budgets_exceeded":{"type":"integer","title":"Budgets Exceeded"},"budgets_on_track":{"type":"integer","title":"Budgets On Track"},"worst_budget":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Worst Budget"},"best_budget":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Best Budget"},"total_budget":{"type":"number","title":"Total Budget"},"total_spent":{"type":"number","title":"Total Spent"},"reimbursables_total":{"type":"number","title":"Reimbursables Total"},"ai_summary":{"type":"string","title":"Ai Summary"},"monthly_trend":{"type":"string","title":"Monthly Trend"},"budget_breakdowns":{"items":{"$ref":"#/components/schemas/BudgetBreakdown"},"type":"array","title":"Budget Breakdowns","default":[]}},"type":"object","required":["health_score","grade","budgets_exceeded","budgets_on_track","total_budget","total_spent","reimbursables_total","ai_summary","monthly_trend"],"title":"BudgetHealthSummary"},"BudgetHistoryEntry":{"properties":{"period_start":{"type":"string","title":"Period Start"},"period_end":{"type":"string","title":"Period End"},"limit_amount":{"type":"number","title":"Limit Amount"},"spent_amount":{"type":"number","title":"Spent Amount"},"utilisation_pct":{"type":"number","title":"Utilisation Pct"},"rolled_over_amount":{"type":"number","title":"Rolled Over Amount"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["period_start","period_end","limit_amount","spent_amount","utilisation_pct","rolled_over_amount","created_at"],"title":"BudgetHistoryEntry"},"BudgetHistoryResponse":{"properties":{"budget_id":{"type":"string","title":"Budget Id"},"category":{"type":"string","title":"Category"},"entries":{"items":{"$ref":"#/components/schemas/BudgetHistoryEntry"},"type":"array","title":"Entries"},"trend":{"type":"string","title":"Trend"},"average_utilisation":{"type":"number","title":"Average Utilisation"},"best_month":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Best Month"},"worst_month":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Worst Month"}},"type":"object","required":["budget_id","category","entries","trend","average_utilisation"],"title":"BudgetHistoryResponse"},"BudgetPeriod":{"type":"string","enum":["weekly","monthly","annual","custom"],"title":"BudgetPeriod"},"BudgetProposal":{"properties":{"category":{"type":"string","title":"Category"},"proposed_limit":{"type":"number","title":"Proposed Limit"},"current_limit":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Limit"},"source":{"type":"string","title":"Source"}},"type":"object","required":["category","proposed_limit","source"],"title":"BudgetProposal","description":"EQ-72 ruling 4: a budget the Payday paths would once have written on\nthe user's behalf. With mode=propose nothing is written; the app shows it\nand the user confirms per budget (PATCH /api/budgets/bulk-update)."},"BudgetResponse":{"properties":{"id":{"type":"string","title":"Id"},"category":{"type":"string","title":"Category"},"monthly_limit":{"type":"number","title":"Monthly Limit"},"period":{"type":"string","title":"Period"},"current_spend":{"type":"number","title":"Current Spend"},"remaining":{"type":"number","title":"Remaining"},"utilisation_pct":{"type":"number","title":"Utilisation Pct"},"period_start":{"type":"string","title":"Period Start"},"period_start_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period Start Date"},"period_end_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period End Date"},"shared_with_partner":{"type":"boolean","title":"Shared With Partner","default":false},"partner_spend":{"type":"number","title":"Partner Spend","default":0},"budget_type":{"type":"string","title":"Budget Type","default":"personal"},"dismissed":{"type":"boolean","title":"Dismissed","default":false},"rollover_enabled":{"type":"boolean","title":"Rollover Enabled","default":false},"rollover_amount":{"type":"number","title":"Rollover Amount","default":0.0},"limit_mode":{"type":"string","title":"Limit Mode","default":"fixed"},"income_percentage":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Income Percentage"},"payday_cycle":{"type":"boolean","title":"Payday Cycle","default":false},"effective_limit":{"type":"number","title":"Effective Limit","default":0.0},"pot_category":{"type":"string","title":"Pot Category","default":"safety_net"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"}},"type":"object","required":["id","category","monthly_limit","period","current_spend","remaining","utilisation_pct","period_start","created_at","updated_at"],"title":"BudgetResponse"},"BudgetSuggestion":{"properties":{"category":{"type":"string","title":"Category"},"suggested_limit":{"type":"number","title":"Suggested Limit"},"current_limit":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Limit"},"average_spend":{"type":"number","title":"Average Spend"},"explanation":{"type":"string","title":"Explanation"},"suggestion_type":{"type":"string","title":"Suggestion Type"}},"type":"object","required":["category","suggested_limit","average_spend","explanation","suggestion_type"],"title":"BudgetSuggestion"},"BudgetUpdate":{"properties":{"base_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Base Updated At"},"monthly_limit":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Monthly Limit"},"period":{"anyOf":[{"$ref":"#/components/schemas/BudgetPeriod"},{"type":"null"}]},"period_start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Period Start Date"},"period_end_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Period End Date"},"shared_with_partner":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Shared With Partner"},"rollover_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Rollover Enabled"},"budget_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Budget Type"},"income_percentage":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Income Percentage"},"payday_cycle":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Payday Cycle"}},"type":"object","title":"BudgetUpdate"},"BulkBudgetItem":{"properties":{"category":{"type":"string","title":"Category"},"new_limit":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"New Limit"}},"type":"object","required":["category","new_limit"],"title":"BulkBudgetItem"},"BulkBudgetUpdateResponse":{"properties":{"updated":{"type":"integer","title":"Updated"},"created":{"type":"integer","title":"Created"}},"type":"object","required":["updated","created"],"title":"BulkBudgetUpdateResponse"},"CGTDisposal":{"properties":{"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date"},"platform":{"type":"string","title":"Platform"},"amount":{"type":"number","title":"Amount"},"transaction_id":{"type":"string","title":"Transaction Id"}},"type":"object","required":["date","platform","amount","transaction_id"],"title":"CGTDisposal"},"CapitalGainsResponse":{"properties":{"current_tax_year_gains":{"type":"number","title":"Current Tax Year Gains"},"annual_allowance":{"type":"number","title":"Annual Allowance"},"allowance_used_pct":{"type":"number","title":"Allowance Used Pct"},"estimated_taxable_gain":{"type":"number","title":"Estimated Taxable Gain"},"estimated_tax_owed":{"type":"number","title":"Estimated Tax Owed"},"taxpayer_band":{"type":"string","title":"Taxpayer Band"},"detected_disposals":{"items":{"$ref":"#/components/schemas/CGTDisposal"},"type":"array","title":"Detected Disposals"},"tax_year_end":{"type":"string","title":"Tax Year End"},"days_until_year_end":{"type":"integer","title":"Days Until Year End"},"allowance_remaining":{"type":"number","title":"Allowance Remaining"},"warning":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Warning"},"disclaimer":{"type":"string","title":"Disclaimer"}},"type":"object","required":["current_tax_year_gains","annual_allowance","allowance_used_pct","estimated_taxable_gain","estimated_tax_owed","taxpayer_band","detected_disposals","tax_year_end","days_until_year_end","allowance_remaining","warning","disclaimer"],"title":"CapitalGainsResponse"},"CashFlowForecastResponse":{"properties":{"status":{"type":"string","title":"Status","default":"ready"},"current_balance":{"type":"number","title":"Current Balance"},"projections":{"items":{"$ref":"#/components/schemas/DailyProjection"},"type":"array","title":"Projections"},"risk":{"$ref":"#/components/schemas/RiskLevel-Output"},"upcoming_bills":{"items":{"$ref":"#/components/schemas/UpcomingBill"},"type":"array","title":"Upcoming Bills"},"recurring_income":{"items":{"$ref":"#/components/schemas/RecurringIncome"},"type":"array","title":"Recurring Income"},"total_recurring_income":{"type":"number","title":"Total Recurring Income"},"total_recurring_expenses":{"type":"number","title":"Total Recurring Expenses"},"ai_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Summary"}},"type":"object","required":["current_balance","projections","risk","upcoming_bills","recurring_income","total_recurring_income","total_recurring_expenses","ai_summary"],"title":"CashFlowForecastResponse"},"CategoryAlternatives":{"properties":{"category":{"type":"string","title":"Category"},"category_label":{"type":"string","title":"Category Label"},"suggestions":{"items":{"$ref":"#/components/schemas/AlternativeSuggestion"},"type":"array","title":"Suggestions"}},"type":"object","required":["category","category_label","suggestions"],"title":"CategoryAlternatives"},"CategoryInfoResponse":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"},"emoji":{"type":"string","title":"Emoji"}},"type":"object","required":["id","label","emoji"],"title":"CategoryInfoResponse"},"CategoryStat":{"properties":{"name":{"type":"string","title":"Name"},"amount":{"type":"number","title":"Amount"},"percentage":{"type":"number","title":"Percentage"},"transactions":{"type":"integer","title":"Transactions"}},"type":"object","required":["name","amount","percentage","transactions"],"title":"CategoryStat"},"ChallengeDetailResponse":{"properties":{"id":{"type":"string","title":"Id"},"challenge_type":{"type":"string","title":"Challenge Type"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"briefing_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Briefing Reason"},"emoji":{"type":"string","title":"Emoji"},"target_amount":{"type":"number","title":"Target Amount"},"current_amount":{"type":"number","title":"Current Amount"},"progress_pct":{"type":"number","title":"Progress Pct"},"difficulty":{"type":"string","title":"Difficulty"},"status":{"type":"string","title":"Status"},"streak_count":{"type":"integer","title":"Streak Count"},"started_at":{"type":"string","title":"Started At"},"expires_at":{"type":"string","title":"Expires At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"},"spending_days":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Spending Days"},"no_spend_days":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"No Spend Days"},"relevant_transactions":{"anyOf":[{"items":{"$ref":"#/components/schemas/TransactionBreakdown"},"type":"array"},{"type":"null"}],"title":"Relevant Transactions"}},"type":"object","required":["id","challenge_type","title","description","emoji","target_amount","current_amount","progress_pct","difficulty","status","streak_count","started_at","expires_at"],"title":"ChallengeDetailResponse"},"ChallengeHistoryItem":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"status":{"type":"string","title":"Status"},"difficulty":{"type":"string","title":"Difficulty"},"target_amount":{"type":"number","title":"Target Amount"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","title","status","difficulty","target_amount"],"title":"ChallengeHistoryItem"},"ChallengeHistoryResponse":{"properties":{"challenges":{"items":{"$ref":"#/components/schemas/ChallengeHistoryItem"},"type":"array","title":"Challenges"},"total_completed":{"type":"integer","title":"Total Completed"},"total_xp_earned":{"type":"integer","title":"Total Xp Earned"},"total_saved":{"type":"number","title":"Total Saved"}},"type":"object","required":["challenges","total_completed","total_xp_earned","total_saved"],"title":"ChallengeHistoryResponse"},"ChallengeResponse":{"properties":{"id":{"type":"string","title":"Id"},"challenge_type":{"type":"string","title":"Challenge Type"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"briefing_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Briefing Reason"},"emoji":{"type":"string","title":"Emoji"},"target_amount":{"type":"number","title":"Target Amount"},"current_amount":{"type":"number","title":"Current Amount"},"progress_pct":{"type":"number","title":"Progress Pct"},"difficulty":{"type":"string","title":"Difficulty"},"status":{"type":"string","title":"Status"},"streak_count":{"type":"integer","title":"Streak Count"},"started_at":{"type":"string","title":"Started At"},"expires_at":{"type":"string","title":"Expires At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","challenge_type","title","description","emoji","target_amount","current_amount","progress_pct","difficulty","status","streak_count","started_at","expires_at"],"title":"ChallengeResponse"},"ChallengesListResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"challenges":{"items":{"$ref":"#/components/schemas/ChallengeResponse"},"type":"array","title":"Challenges"},"total_active":{"type":"integer","title":"Total Active"},"total_completed":{"type":"integer","title":"Total Completed"},"current_streak":{"type":"integer","title":"Current Streak"}},"type":"object","required":["user_id","challenges","total_active","total_completed","current_streak"],"title":"ChallengesListResponse"},"CheckRewardsResponse":{"properties":{"rewards_granted":{"type":"integer","title":"Rewards Granted"},"message":{"type":"string","title":"Message"}},"type":"object","required":["rewards_granted","message"],"title":"CheckRewardsResponse"},"CheckoutRequest":{"properties":{"tier":{"type":"string","enum":["plus","pro","unlimited"],"title":"Tier"}},"type":"object","required":["tier"],"title":"CheckoutRequest"},"ClaimResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"premium_months_awarded":{"type":"integer","title":"Premium Months Awarded"}},"type":"object","required":["success","message","premium_months_awarded"],"title":"ClaimResponse"},"ClickRequest":{"properties":{"recommendation_id":{"type":"string","maxLength":100,"title":"Recommendation Id"},"product_id":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Product Id"}},"type":"object","required":["recommendation_id"],"title":"ClickRequest"},"ClientDriftResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"client_label":{"type":"string","title":"Client Label"},"period_label":{"type":"string","title":"Period Label"},"scanned_at":{"type":"string","format":"date-time","title":"Scanned At"},"alert_count":{"type":"integer","title":"Alert Count"},"highest_severity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Highest Severity"},"alerts":{"items":{"$ref":"#/components/schemas/DriftAlertOut"},"type":"array","title":"Alerts"},"rules_not_run":{"items":{"$ref":"#/components/schemas/RuleNotRun"},"type":"array","title":"Rules Not Run"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"rules":{"items":{"$ref":"#/components/schemas/RuleDescription"},"type":"array","title":"Rules"},"derivation":{"type":"string","title":"Derivation"}},"type":"object","required":["user_id","client_label","period_label","scanned_at","alert_count","highest_severity","alerts","rules_not_run","scopes","rules","derivation"],"title":"ClientDriftResponse"},"ClientExceptionsResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"client_label":{"type":"string","title":"Client Label"},"period_start":{"type":"string","format":"date","title":"Period Start"},"period_end":{"type":"string","format":"date","title":"Period End"},"pending_count":{"type":"integer","title":"Pending Count"},"exceptions":{"items":{"$ref":"#/components/schemas/ExceptionItem"},"type":"array","title":"Exceptions"}},"type":"object","required":["user_id","client_label","period_start","period_end","pending_count","exceptions"],"title":"ClientExceptionsResponse"},"ClientGrantResponse":{"properties":{"grant_id":{"type":"string","title":"Grant Id"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"client_label":{"type":"string","title":"Client Label"},"status":{"type":"string","title":"Status"},"scope":{"type":"string","title":"Scope"},"can_recategorise":{"type":"boolean","title":"Can Recategorise"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"invited_at":{"type":"string","format":"date-time","title":"Invited At"},"accepted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Accepted At"},"last_synced_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Synced At"},"pending_exceptions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pending Exceptions"}},"type":"object","required":["grant_id","user_id","client_label","status","scope","can_recategorise","scopes","invited_at","accepted_at","last_synced_at","pending_exceptions"],"title":"ClientGrantResponse"},"ClientIncomeResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"client_label":{"type":"string","title":"Client Label"},"monthly_income":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Monthly Income"},"detected_payday_day":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Detected Payday Day"},"next_payday":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Next Payday"},"days_until_payday":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days Until Payday"},"sources":{"items":{"$ref":"#/components/schemas/IncomeSourceItem"},"type":"array","title":"Sources"},"monthly_income_from_sources":{"type":"number","title":"Monthly Income From Sources"},"allocations":{"items":{"$ref":"#/components/schemas/PaydayRuleItem"},"type":"array","title":"Allocations"},"total_allocated":{"type":"number","title":"Total Allocated"},"spent_so_far_this_month":{"type":"number","title":"Spent So Far This Month"},"safe_to_spend_remaining":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Safe To Spend Remaining"}},"type":"object","required":["user_id","client_label","monthly_income","detected_payday_day","next_payday","days_until_payday","sources","monthly_income_from_sources","allocations","total_allocated","spent_so_far_this_month","safe_to_spend_remaining"],"title":"ClientIncomeResponse"},"ClientSummaryResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"client_label":{"type":"string","title":"Client Label"},"period_start":{"type":"string","format":"date","title":"Period Start"},"period_end":{"type":"string","format":"date","title":"Period End"},"months":{"type":"integer","title":"Months"},"total_expenditure":{"type":"number","title":"Total Expenditure"},"pots":{"items":{"$ref":"#/components/schemas/app__api__adviser__PotSummary"},"type":"array","title":"Pots"},"monthly":{"items":{"$ref":"#/components/schemas/MonthlyPoint"},"type":"array","title":"Monthly"}},"type":"object","required":["user_id","client_label","period_start","period_end","months","total_expenditure","pots","monthly"],"title":"ClientSummaryResponse"},"CoachBuffer":{"properties":{"cash_saved":{"type":"number","title":"Cash Saved"},"target":{"type":"number","title":"Target"},"months":{"type":"number","title":"Months"},"target_months":{"type":"integer","title":"Target Months"}},"type":"object","required":["cash_saved","target","months","target_months"],"title":"CoachBuffer","description":"The cash buffer the coach measures Savings against, in pounds (26 Sep 2026)."},"CombinedBill":{"properties":{"merchant":{"type":"string","title":"Merchant"},"amount":{"type":"number","title":"Amount"},"paid_by":{"type":"string","title":"Paid By"},"paid_by_name":{"type":"string","title":"Paid By Name"},"frequency":{"type":"string","title":"Frequency"}},"type":"object","required":["merchant","amount","paid_by","paid_by_name","frequency"],"title":"CombinedBill"},"CombinedBillsResponse":{"properties":{"bills":{"items":{"$ref":"#/components/schemas/CombinedBill"},"type":"array","title":"Bills"},"user1_total":{"type":"number","title":"User1 Total"},"user2_total":{"type":"number","title":"User2 Total"},"overlap_suggestions":{"items":{"type":"string"},"type":"array","title":"Overlap Suggestions"}},"type":"object","required":["bills","user1_total","user2_total","overlap_suggestions"],"title":"CombinedBillsResponse"},"CombinedImpact":{"properties":{"monthly":{"type":"number","title":"Monthly"},"annual":{"type":"number","title":"Annual"},"five_year":{"type":"number","title":"Five Year"}},"type":"object","required":["monthly","annual","five_year"],"title":"CombinedImpact"},"CombinedSpendingResponse":{"properties":{"user1_spending":{"additionalProperties":{"type":"number"},"type":"object","title":"User1 Spending"},"user2_spending":{"additionalProperties":{"type":"number"},"type":"object","title":"User2 Spending"},"combined":{"additionalProperties":{"type":"number"},"type":"object","title":"Combined"},"categories":{"items":{"type":"string"},"type":"array","title":"Categories"},"user1_total":{"type":"number","title":"User1 Total"},"user2_total":{"type":"number","title":"User2 Total"},"combined_total":{"type":"number","title":"Combined Total"},"user1_name":{"type":"string","title":"User1 Name"},"user2_name":{"type":"string","title":"User2 Name"}},"type":"object","required":["user1_spending","user2_spending","combined","categories","user1_total","user2_total","combined_total","user1_name","user2_name"],"title":"CombinedSpendingResponse"},"CommentaryOut":{"properties":{"rule":{"type":"string","title":"Rule"},"text":{"type":"string","title":"Text"}},"type":"object","required":["rule","text"],"title":"CommentaryOut"},"CompleteAddBankRequest":{"properties":{"consent_link_id":{"type":"string","title":"Consent Link Id"}},"type":"object","required":["consent_link_id"],"title":"CompleteAddBankRequest"},"CompleteAddBankResponse":{"properties":{"status":{"type":"string","title":"Status"},"synced_accounts":{"type":"integer","title":"Synced Accounts"},"new_transactions":{"type":"integer","title":"New Transactions"},"connections":{"items":{"$ref":"#/components/schemas/BankConnectionResponse"},"type":"array","title":"Connections"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["status","synced_accounts","new_transactions","connections"],"title":"CompleteAddBankResponse"},"CompletenessChip":{"properties":{"label":{"type":"string","title":"Label"},"done":{"type":"boolean","title":"Done"},"points":{"type":"integer","title":"Points"}},"type":"object","required":["label","done","points"],"title":"CompletenessChip"},"ConfirmBody":{"properties":{"wrapper_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wrapper Type"},"account_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Account Id"},"amount":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Amount"},"date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date"},"is_employer":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Employer"},"link_networth_account_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Link Networth Account Id"},"remember_reference":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Remember Reference"}},"type":"object","title":"ConfirmBody"},"ConfirmRequest":{"properties":{"new_provider":{"type":"string","title":"New Provider"},"new_monthly_cost":{"type":"number","title":"New Monthly Cost"},"stayed":{"type":"boolean","title":"Stayed","default":false}},"type":"object","required":["new_provider","new_monthly_cost"],"title":"ConfirmRequest"},"ConfirmResponse":{"properties":{"id":{"type":"string","title":"Id"},"category":{"type":"string","title":"Category"},"estimated_annual_saving":{"type":"number","title":"Estimated Annual Saving"},"xp_awarded":{"type":"integer","title":"Xp Awarded"},"is_first_switch":{"type":"boolean","title":"Is First Switch"},"badge_unlocked":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Badge Unlocked"}},"type":"object","required":["id","category","estimated_annual_saving","xp_awarded","is_first_switch"],"title":"ConfirmResponse"},"ConfirmSubscriptionRequest":{"properties":{"merchant_name":{"type":"string","title":"Merchant Name"},"amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Amount"},"frequency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Frequency","default":"monthly"},"billing_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Type"}},"type":"object","required":["merchant_name"],"title":"ConfirmSubscriptionRequest"},"ConnectionResponse":{"properties":{"id":{"type":"string","title":"Id"},"provider":{"type":"string","title":"Provider"},"institution_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Institution Id"},"institution_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Institution Name"},"status":{"type":"string","title":"Status"},"connected_at":{"type":"string","title":"Connected At"},"last_synced_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Synced At"},"last_sync_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Sync Status"},"import_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Import State"},"first_import_next_attempt_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Import Next Attempt At"}},"type":"object","required":["id","provider","institution_id","institution_name","status","connected_at","last_synced_at"],"title":"ConnectionResponse"},"ConsentActionResponse":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"}},"type":"object","required":["id","status"],"title":"ConsentActionResponse"},"ConsentItem":{"properties":{"id":{"type":"string","title":"Id"},"firm_name":{"type":"string","title":"Firm Name"},"scope":{"type":"string","title":"Scope"},"can_recategorise":{"type":"boolean","title":"Can Recategorise"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"covers":{"items":{"type":"string"},"type":"array","title":"Covers"},"status":{"type":"string","title":"Status"},"invited_at":{"type":"string","format":"date-time","title":"Invited At"},"accepted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Accepted At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"sponsored_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sponsored Tier"}},"type":"object","required":["id","firm_name","scope","can_recategorise","scopes","covers","status","invited_at","accepted_at","expires_at","sponsored_tier"],"title":"ConsentItem"},"ConsentScope":{"type":"string","enum":["category_totals","full_transactions"],"title":"ConsentScope","description":"What an active grant lets the firm's advisers read."},"ContractRenewal":{"properties":{"merchant":{"type":"string","title":"Merchant"},"monthly_amount":{"type":"number","title":"Monthly Amount"},"months_active":{"type":"integer","title":"Months Active"},"estimated_renewal_date":{"type":"string","title":"Estimated Renewal Date"},"annual_cost":{"type":"number","title":"Annual Cost"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},"type":"object","required":["merchant","monthly_amount","months_active","estimated_renewal_date","annual_cost","category"],"title":"ContractRenewal"},"ContributeRequest":{"properties":{"amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Amount"},"contribution_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Contribution Id"}},"type":"object","required":["amount"],"title":"ContributeRequest"},"ContributionCreate":{"properties":{"account_id":{"type":"string","format":"uuid","title":"Account Id"},"amount":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Amount"},"date":{"type":"string","format":"date","title":"Date"},"is_employer":{"type":"boolean","title":"Is Employer","default":false},"transaction_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Transaction Id"}},"type":"object","required":["account_id","amount","date"],"title":"ContributionCreate"},"ContributionPatch":{"properties":{"account_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Account Id"},"amount":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Amount"},"date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date"},"is_employer":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Employer"}},"type":"object","title":"ContributionPatch"},"CorrectionRequest":{"properties":{"target_type":{"type":"string","title":"Target Type","description":"stream | habit | trait"},"target_key":{"type":"string","maxLength":300,"minLength":1,"title":"Target Key"},"correction":{"type":"string","title":"Correction","description":"not_a_bill | one_off | transfer | not_a_habit | dismiss | confirm"},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Note"}},"type":"object","required":["target_type","target_key","correction"],"title":"CorrectionRequest"},"CorrectionResponse":{"properties":{"id":{"type":"string","title":"Id"},"target_type":{"type":"string","title":"Target Type"},"target_key":{"type":"string","title":"Target Key"},"correction":{"type":"string","title":"Correction"},"locked":{"type":"boolean","title":"Locked"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","target_type","target_key","correction","locked"],"title":"CorrectionResponse"},"CreateSessionRequest":{"properties":{"title":{"type":"string","maxLength":255,"title":"Title","default":"New chat"}},"type":"object","title":"CreateSessionRequest"},"CreateTargetRequest":{"properties":{"label":{"type":"string","maxLength":100,"minLength":1,"title":"Label"},"sort_code":{"anyOf":[{"type":"string","maxLength":8,"minLength":6},{"type":"null"}],"title":"Sort Code"},"account_number":{"anyOf":[{"type":"string","maxLength":8,"minLength":8},{"type":"null"}],"title":"Account Number"},"source_connection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Connection Id"},"holder_name":{"type":"string","maxLength":255,"minLength":1,"title":"Holder Name"},"goal_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Goal Id"}},"type":"object","required":["label","holder_name"],"title":"CreateTargetRequest"},"CreatedItem":{"properties":{"type":{"type":"string","title":"Type"},"category":{"type":"string","title":"Category"},"amount":{"type":"number","title":"Amount"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"}},"type":"object","required":["type","category","amount"],"title":"CreatedItem"},"CronResponse":{"properties":{"status":{"type":"string","title":"Status"},"users_checked":{"type":"integer","title":"Users Checked"},"notifications_sent":{"type":"integer","title":"Notifications Sent"}},"type":"object","required":["status","users_checked","notifications_sent"],"title":"CronResponse"},"CustomAIReportRequest":{"properties":{"period":{"type":"string","title":"Period"},"prompt":{"type":"string","title":"Prompt"}},"type":"object","required":["period","prompt"],"title":"CustomAIReportRequest"},"CycleReview":{"properties":{"period_start":{"type":"string","title":"Period Start"},"period_end":{"type":"string","title":"Period End"},"headline":{"type":"string","title":"Headline"},"entries":{"items":{"$ref":"#/components/schemas/CycleReviewEntry"},"type":"array","title":"Entries"}},"type":"object","required":["period_start","period_end","headline","entries"],"title":"CycleReview","description":"How the previous pay cycle went against the accepted plan."},"CycleReviewEntry":{"properties":{"category":{"type":"string","title":"Category"},"planned":{"type":"number","title":"Planned"},"actual":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Actual"},"delta":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Delta"}},"type":"object","required":["category","planned"],"title":"CycleReviewEntry"},"DBRulesResponse":{"properties":{"rules":{"items":{"$ref":"#/components/schemas/PaydayRule"},"type":"array","title":"Rules"},"total_allocated":{"type":"number","title":"Total Allocated","default":0},"remaining_after_rules":{"type":"number","title":"Remaining After Rules","default":0},"timeline":{"items":{"$ref":"#/components/schemas/TimelineEvent"},"type":"array","title":"Timeline","default":[]},"budget_proposals":{"items":{"$ref":"#/components/schemas/BudgetProposal"},"type":"array","title":"Budget Proposals","default":[]}},"type":"object","required":["rules"],"title":"DBRulesResponse"},"DailyCompleteRequest":{"properties":{"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"idempotent":{"type":"boolean","title":"Idempotent","default":false}},"type":"object","title":"DailyCompleteRequest","description":"Sent by the local-first app; a request with no body behaves as before."},"DailyInsightResponse":{"properties":{"id":{"type":"string","title":"Id"},"insight_type":{"type":"string","title":"Insight Type"},"content":{"type":"string","title":"Content"},"shown_date":{"type":"string","title":"Shown Date"}},"type":"object","required":["id","insight_type","content","shown_date"],"title":"DailyInsightResponse"},"DailyLoginResponse":{"properties":{"already_awarded":{"type":"boolean","title":"Already Awarded"},"xp_awarded":{"type":"integer","title":"Xp Awarded"},"total_xp":{"type":"integer","title":"Total Xp"},"level":{"type":"integer","title":"Level"},"level_name":{"type":"string","title":"Level Name"},"leveled_up":{"type":"boolean","title":"Leveled Up"}},"type":"object","required":["already_awarded","xp_awarded","total_xp","level","level_name","leveled_up"],"title":"DailyLoginResponse"},"DailyProjection":{"properties":{"date":{"type":"string","title":"Date"},"projected_balance":{"type":"number","title":"Projected Balance"},"income":{"type":"number","title":"Income"},"expenses":{"type":"number","title":"Expenses"},"known_items":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Known Items"}},"type":"object","required":["date","projected_balance","income","expenses","known_items"],"title":"DailyProjection"},"DeepAnalysisResponse":{"properties":{"modules":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Modules"},"summaries":{"additionalProperties":{"type":"string"},"type":"object","title":"Summaries"},"generated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Generated At"}},"type":"object","required":["modules","summaries"],"title":"DeepAnalysisResponse"},"DeleteAccountRequest":{"properties":{"password":{"type":"string","title":"Password"},"rationale":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rationale"}},"type":"object","required":["password"],"title":"DeleteAccountRequest"},"DemoSummaryResponse":{"properties":{"account":{"additionalProperties":true,"type":"object","title":"Account"},"connection":{"additionalProperties":true,"type":"object","title":"Connection"},"transaction_summary":{"additionalProperties":true,"type":"object","title":"Transaction Summary"}},"type":"object","required":["account","connection","transaction_summary"],"title":"DemoSummaryResponse"},"DetectResponse":{"properties":{"anomalies":{"items":{"$ref":"#/components/schemas/AnomalyResponse"},"type":"array","title":"Anomalies"},"total":{"type":"integer","title":"Total"},"cached":{"type":"boolean","title":"Cached"}},"type":"object","required":["anomalies","total","cached"],"title":"DetectResponse"},"DetectTransfersResponse":{"properties":{"pairs_detected":{"type":"integer","title":"Pairs Detected"}},"type":"object","required":["pairs_detected"],"title":"DetectTransfersResponse"},"DisconnectResponse":{"properties":{"connection_id":{"type":"string","title":"Connection Id"},"status":{"type":"string","title":"Status"},"disconnected_at":{"type":"string","title":"Disconnected At"},"transactions_preserved":{"type":"boolean","title":"Transactions Preserved"},"accounts_archived":{"type":"integer","title":"Accounts Archived"}},"type":"object","required":["connection_id","status","disconnected_at","transactions_preserved","accounts_archived"],"title":"DisconnectResponse"},"DismissAlertRequest":{"properties":{"budget_id":{"type":"string","title":"Budget Id"},"period_start":{"type":"string","title":"Period Start"}},"type":"object","required":["budget_id","period_start"],"title":"DismissAlertRequest"},"DismissRequest":{"properties":{"snooze":{"type":"boolean","title":"Snooze","default":false}},"type":"object","title":"DismissRequest"},"DismissSubscriptionRequest":{"properties":{"merchant_name":{"type":"string","title":"Merchant Name"}},"type":"object","required":["merchant_name"],"title":"DismissSubscriptionRequest"},"DriftAlertOut":{"properties":{"rule":{"type":"string","title":"Rule"},"severity":{"type":"string","title":"Severity"},"subject":{"type":"string","title":"Subject"},"headline":{"type":"string","title":"Headline"},"detail":{"type":"string","title":"Detail"},"threshold":{"type":"string","title":"Threshold"},"current":{"type":"number","title":"Current"},"prior":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Prior"},"change_abs":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Abs"},"change_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct"},"period_label":{"type":"string","title":"Period Label"},"scope_required":{"type":"string","title":"Scope Required"},"fingerprint":{"type":"string","title":"Fingerprint"}},"type":"object","required":["rule","severity","subject","headline","detail","threshold","current","prior","change_abs","change_pct","period_label","scope_required","fingerprint"],"title":"DriftAlertOut"},"DuplicateCharge":{"properties":{"merchant":{"type":"string","title":"Merchant"},"charge_1_amount":{"type":"number","title":"Charge 1 Amount"},"charge_2_amount":{"type":"number","title":"Charge 2 Amount"},"charge_1_date":{"type":"string","title":"Charge 1 Date"},"charge_2_date":{"type":"string","title":"Charge 2 Date"},"potential_saving":{"type":"number","title":"Potential Saving"}},"type":"object","required":["merchant","charge_1_amount","charge_2_amount","charge_1_date","charge_2_date","potential_saving"],"title":"DuplicateCharge"},"EmailReportResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"emails_sent":{"type":"integer","title":"Emails Sent","default":0}},"type":"object","required":["success","message"],"title":"EmailReportResponse"},"EntitlementResponse":{"properties":{"tier":{"type":"string","title":"Tier"},"source":{"type":"string","enum":["apple","stripe","sponsored","grant","none"],"title":"Source"}},"type":"object","required":["tier","source"],"title":"EntitlementResponse"},"EscalateRequest":{"properties":{"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"},"reason":{"type":"string","maxLength":500,"title":"Reason","default":"User requested human support"}},"type":"object","title":"EscalateRequest"},"EscalateResponse":{"properties":{"ticket_id":{"type":"string","title":"Ticket Id"},"message":{"type":"string","title":"Message"}},"type":"object","required":["ticket_id","message"],"title":"EscalateResponse"},"ExceptionItem":{"properties":{"transaction_id":{"type":"string","title":"Transaction Id"},"date":{"type":"string","format":"date","title":"Date"},"description":{"type":"string","title":"Description"},"merchant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Merchant Name"},"amount":{"type":"number","title":"Amount"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"reason":{"type":"string","title":"Reason"},"label":{"type":"string","title":"Label"},"severity":{"type":"string","title":"Severity"}},"type":"object","required":["transaction_id","date","description","merchant_name","amount","category","reason","label","severity"],"title":"ExceptionItem"},"ExecuteActionRequest":{"properties":{"action_type":{"type":"string","title":"Action Type"},"params":{"additionalProperties":true,"type":"object","title":"Params"}},"type":"object","required":["action_type"],"title":"ExecuteActionRequest"},"ExecuteActionResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"created_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created Id"}},"type":"object","required":["success","message"],"title":"ExecuteActionResponse"},"ExportResponse":{"properties":{"export_id":{"type":"string","title":"Export Id"},"download_url":{"type":"string","title":"Download Url"},"filename":{"type":"string","title":"Filename"},"format":{"type":"string","title":"Format"},"file_size":{"type":"integer","title":"File Size"},"ai_generated":{"type":"boolean","title":"Ai Generated","default":false}},"type":"object","required":["export_id","download_url","filename","format","file_size"],"title":"ExportResponse"},"FeedbackRequest":{"properties":{"rating":{"type":"string","pattern":"^(positive|negative)$","title":"Rating"},"feedback_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feedback Text"}},"type":"object","required":["rating"],"title":"FeedbackRequest"},"FeedbackStats":{"properties":{"total_ratings":{"type":"integer","title":"Total Ratings"},"positive_rate_pct":{"type":"number","title":"Positive Rate Pct"},"ratings_last_7_days":{"type":"integer","title":"Ratings Last 7 Days"}},"type":"object","required":["total_ratings","positive_rate_pct","ratings_last_7_days"],"title":"FeedbackStats"},"FinancialCompleteness":{"properties":{"score":{"type":"integer","title":"Score"},"chips":{"items":{"$ref":"#/components/schemas/CompletenessChip"},"type":"array","title":"Chips"}},"type":"object","required":["score","chips"],"title":"FinancialCompleteness"},"FinancialPersonality":{"properties":{"type":{"type":"string","title":"Type"},"name":{"type":"string","title":"Name"},"emoji":{"type":"string","title":"Emoji"},"description":{"type":"string","title":"Description"},"score":{"type":"number","title":"Score"},"computed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Computed At"}},"type":"object","required":["type","name","emoji","description","score"],"title":"FinancialPersonality"},"FirmDriftClient":{"properties":{"user_id":{"type":"string","title":"User Id"},"client_label":{"type":"string","title":"Client Label"},"alert_count":{"type":"integer","title":"Alert Count"},"highest_severity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Highest Severity"},"alerts":{"items":{"$ref":"#/components/schemas/DriftAlertOut"},"type":"array","title":"Alerts"}},"type":"object","required":["user_id","client_label","alert_count","highest_severity","alerts"],"title":"FirmDriftClient"},"FirmDriftResponse":{"properties":{"firm_name":{"type":"string","title":"Firm Name"},"scanned_at":{"type":"string","format":"date-time","title":"Scanned At"},"period_label":{"type":"string","title":"Period Label"},"clients_scanned":{"type":"integer","title":"Clients Scanned"},"clients_with_alerts":{"type":"integer","title":"Clients With Alerts"},"total_alerts":{"type":"integer","title":"Total Alerts"},"clients":{"items":{"$ref":"#/components/schemas/FirmDriftClient"},"type":"array","title":"Clients"},"rules":{"items":{"$ref":"#/components/schemas/RuleDescription"},"type":"array","title":"Rules"},"derivation":{"type":"string","title":"Derivation"}},"type":"object","required":["firm_name","scanned_at","period_label","clients_scanned","clients_with_alerts","total_alerts","clients","rules","derivation"],"title":"FirmDriftResponse"},"ForgotPasswordRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"ForgotPasswordRequest"},"GenerateResponse":{"properties":{"referral_code":{"type":"string","title":"Referral Code"}},"type":"object","required":["referral_code"],"title":"GenerateResponse"},"GoalCategory":{"type":"string","enum":["house_deposit","emergency_fund","holiday","wedding","retirement","education","car","investment","custom"],"title":"GoalCategory"},"GoalMilestone":{"properties":{"percentage":{"type":"integer","title":"Percentage"},"xp_awarded":{"type":"integer","title":"Xp Awarded"},"goal_name":{"type":"string","title":"Goal Name"}},"type":"object","required":["percentage","xp_awarded","goal_name"],"title":"GoalMilestone"},"GoalProgress":{"properties":{"name":{"type":"string","title":"Name"},"target":{"type":"number","title":"Target"},"current":{"type":"number","title":"Current"},"percentage":{"type":"number","title":"Percentage"}},"type":"object","required":["name","target","current","percentage"],"title":"GoalProgress"},"GoalSplit":{"properties":{"goal_id":{"type":"string","title":"Goal Id"},"name":{"type":"string","title":"Name"},"amount":{"type":"number","title":"Amount"}},"type":"object","required":["goal_id","name","amount"],"title":"GoalSplit"},"GoalUnplanned":{"properties":{"goal_id":{"type":"string","title":"Goal Id"},"name":{"type":"string","title":"Name"},"note":{"type":"string","title":"Note","default":"Set a target to plan this goal"}},"type":"object","required":["goal_id","name"],"title":"GoalUnplanned","description":"A goal with no monthly amount and no date: the plan gives it nothing\nand says so (13 Oct 2026)."},"GoogleAuthRequest":{"properties":{"id_token":{"type":"string","title":"Id Token"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref"}},"type":"object","required":["id_token"],"title":"GoogleAuthRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HabitGroup":{"properties":{"name":{"type":"string","title":"Name"},"merchants":{"items":{"$ref":"#/components/schemas/HabitMerchant"},"type":"array","title":"Merchants"},"total_monthly":{"type":"number","title":"Total Monthly"},"total_count":{"type":"integer","title":"Total Count"}},"type":"object","required":["name","merchants","total_monthly","total_count"],"title":"HabitGroup"},"HabitMerchant":{"properties":{"merchant":{"type":"string","title":"Merchant"},"total_spend":{"type":"number","title":"Total Spend"},"count":{"type":"integer","title":"Count"},"avg_amount":{"type":"number","title":"Avg Amount"},"last_date":{"type":"string","title":"Last Date"},"user_overridden":{"type":"boolean","title":"User Overridden","default":false}},"type":"object","required":["merchant","total_spend","count","avg_amount","last_date"],"title":"HabitMerchant"},"HistoryResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"snapshots":{"items":{"$ref":"#/components/schemas/SnapshotResponse"},"type":"array","title":"Snapshots"}},"type":"object","required":["user_id","snapshots"],"title":"HistoryResponse"},"HpiRefreshResponse":{"properties":{"status":{"type":"string","title":"Status"},"slugs_checked":{"type":"integer","title":"Slugs Checked"},"slugs_updated":{"type":"integer","title":"Slugs Updated"},"properties_healed":{"type":"integer","title":"Properties Healed"},"errors":{"type":"integer","title":"Errors"}},"type":"object","required":["status","slugs_checked","slugs_updated","properties_healed","errors"],"title":"HpiRefreshResponse"},"IQActivity":{"properties":{"actions_taken":{"type":"integer","title":"Actions Taken"},"insights_delivered":{"type":"integer","title":"Insights Delivered"},"notifications_sent":{"type":"integer","title":"Notifications Sent"},"money_moved":{"type":"number","title":"Money Moved"},"recent":{"items":{"$ref":"#/components/schemas/IQActivityItem"},"type":"array","title":"Recent"}},"type":"object","required":["actions_taken","insights_delivered","notifications_sent","money_moved","recent"],"title":"IQActivity"},"IQActivityItem":{"properties":{"type":{"type":"string","title":"Type"},"title":{"type":"string","title":"Title"},"timestamp":{"type":"string","title":"Timestamp"},"icon":{"type":"string","title":"Icon"}},"type":"object","required":["type","title","timestamp","icon"],"title":"IQActivityItem"},"IQDashboardResponse":{"properties":{"greeting":{"type":"string","title":"Greeting"},"financial_completeness":{"$ref":"#/components/schemas/FinancialCompleteness"},"iq_activity":{"$ref":"#/components/schemas/IQActivity"},"recommendations":{"items":{"$ref":"#/components/schemas/IQRecommendation"},"type":"array","title":"Recommendations"},"financial_personality":{"$ref":"#/components/schemas/FinancialPersonality"},"iq_stats":{"$ref":"#/components/schemas/IQStats"},"feedback_stats":{"anyOf":[{"$ref":"#/components/schemas/FeedbackStats"},{"type":"null"}]},"training_stats":{"anyOf":[{"$ref":"#/components/schemas/TrainingStats"},{"type":"null"}]}},"type":"object","required":["greeting","financial_completeness","iq_activity","recommendations","financial_personality","iq_stats"],"title":"IQDashboardResponse"},"IQRecommendation":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"priority":{"type":"integer","title":"Priority"},"category":{"type":"string","title":"Category"},"action_route":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action Route"},"icon":{"type":"string","title":"Icon"},"external_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Url"}},"type":"object","required":["id","title","description","priority","category","action_route","icon"],"title":"IQRecommendation"},"IQStats":{"properties":{"member_since":{"type":"string","title":"Member Since"},"total_transactions_analysed":{"type":"integer","title":"Total Transactions Analysed"},"iq_conversations":{"type":"integer","title":"Iq Conversations"},"xp_level":{"type":"integer","title":"Xp Level"},"xp_total":{"type":"integer","title":"Xp Total"},"streak_days":{"type":"integer","title":"Streak Days"}},"type":"object","required":["member_since","total_transactions_analysed","iq_conversations","xp_level","xp_total","streak_days"],"title":"IQStats"},"ISAAllowanceResponse":{"properties":{"annual_allowance":{"type":"number","title":"Annual Allowance"},"tracked":{"type":"boolean","title":"Tracked","default":true},"total_contributed":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Contributed"},"remaining":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Remaining"},"plans":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Plans"}},"type":"object","required":["annual_allowance","total_contributed","remaining","plans"],"title":"ISAAllowanceResponse"},"IncomeConfirmRequest":{"properties":{"sources":{"items":{"$ref":"#/components/schemas/IncomeSourceCreate"},"type":"array","title":"Sources"}},"type":"object","required":["sources"],"title":"IncomeConfirmRequest"},"IncomeOut":{"properties":{"received_current":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Received Current"},"received_prior":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Received Prior"},"stated_monthly_income":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Stated Monthly Income"},"stated_annual_equivalent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Stated Annual Equivalent"},"source":{"$ref":"#/components/schemas/SourceNoteOut"},"stated_source":{"anyOf":[{"$ref":"#/components/schemas/SourceNoteOut"},{"type":"null"}]}},"type":"object","required":["received_current","received_prior","stated_monthly_income","stated_annual_equivalent","source"],"title":"IncomeOut"},"IncomeSourceCreate":{"properties":{"label":{"type":"string","title":"Label"},"income_type":{"type":"string","title":"Income Type"},"amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Amount"},"source_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Description"},"account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Id"},"frequency":{"type":"string","title":"Frequency","default":"monthly"},"is_primary_salary":{"type":"boolean","title":"Is Primary Salary","default":false}},"type":"object","required":["label","income_type","amount"],"title":"IncomeSourceCreate"},"IncomeSourceItem":{"properties":{"label":{"type":"string","title":"Label"},"income_type":{"type":"string","title":"Income Type"},"amount":{"type":"number","title":"Amount"},"frequency":{"type":"string","title":"Frequency"},"is_primary_salary":{"type":"boolean","title":"Is Primary Salary"},"confirmed_by_user":{"type":"boolean","title":"Confirmed By User"}},"type":"object","required":["label","income_type","amount","frequency","is_primary_salary","confirmed_by_user"],"title":"IncomeSourceItem"},"IncomeSourceUpdate":{"properties":{"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"income_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Income Type"},"amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Amount"},"source_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Description"},"account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Id"},"frequency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Frequency"},"is_primary_salary":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Primary Salary"}},"type":"object","title":"IncomeSourceUpdate"},"InitiateAllocationRequest":{"properties":{"source_account_id":{"type":"string","title":"Source Account Id"},"rules":{"items":{"$ref":"#/components/schemas/AllocationRuleItem"},"type":"array","title":"Rules"}},"type":"object","required":["source_account_id","rules"],"title":"InitiateAllocationRequest"},"InitiatePaymentRequest":{"properties":{"source_account_id":{"type":"string","title":"Source Account Id"},"target_id":{"type":"string","title":"Target Id"},"amount":{"type":"number","exclusiveMinimum":0.0,"title":"Amount"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["source_account_id","target_id","amount"],"title":"InitiatePaymentRequest"},"InsightItem":{"properties":{"message":{"type":"string","title":"Message"},"severity":{"type":"string","title":"Severity"}},"type":"object","required":["message","severity"],"title":"InsightItem"},"InsightsResponse":{"properties":{"insights":{"items":{"$ref":"#/components/schemas/InsightItem"},"type":"array","title":"Insights"}},"type":"object","required":["insights"],"title":"InsightsResponse"},"InvestmentCreate":{"properties":{"name":{"type":"string","title":"Name"},"monthly_amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Monthly Amount"},"risk_level":{"$ref":"#/components/schemas/RiskLevel-Input","default":"balanced"},"time_horizon_years":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Time Horizon Years","default":10},"current_portfolio_value":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Current Portfolio Value","default":"0"},"target_amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Target Amount"},"isa_contributions_this_year":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Isa Contributions This Year","default":"0"}},"type":"object","required":["name","monthly_amount"],"title":"InvestmentCreate"},"InvestmentResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"monthly_amount":{"type":"number","title":"Monthly Amount"},"risk_level":{"type":"string","title":"Risk Level"},"time_horizon_years":{"type":"integer","title":"Time Horizon Years"},"current_portfolio_value":{"type":"number","title":"Current Portfolio Value"},"target_amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Target Amount"},"isa_contributions_this_year":{"type":"number","title":"Isa Contributions This Year"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["id","name","monthly_amount","risk_level","time_horizon_years","current_portfolio_value","target_amount","isa_contributions_this_year","created_at","updated_at"],"title":"InvestmentResponse"},"InvestmentUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"monthly_amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Monthly Amount"},"risk_level":{"anyOf":[{"$ref":"#/components/schemas/RiskLevel-Input"},{"type":"null"}]},"time_horizon_years":{"anyOf":[{"type":"integer","maximum":50.0,"minimum":1.0},{"type":"null"}],"title":"Time Horizon Years"},"current_portfolio_value":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Current Portfolio Value"},"target_amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Target Amount"},"isa_contributions_this_year":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Isa Contributions This Year"}},"type":"object","title":"InvestmentUpdate"},"IsaStatusResponse":{"properties":{"allowance_total":{"type":"number","title":"Allowance Total"},"tracked":{"type":"boolean","title":"Tracked","default":true},"allowance_used":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Allowance Used"},"allowance_remaining":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Allowance Remaining"},"days_until_deadline":{"type":"integer","title":"Days Until Deadline"},"deadline_date":{"type":"string","title":"Deadline Date"},"recommended_split":{"additionalProperties":true,"type":"object","title":"Recommended Split"},"has_lisa_potential":{"type":"boolean","title":"Has Lisa Potential"},"lisa_bonus_amount":{"type":"number","title":"Lisa Bonus Amount"},"monthly_to_max_isa":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Monthly To Max Isa"}},"type":"object","required":["allowance_total","allowance_used","allowance_remaining","days_until_deadline","deadline_date","recommended_split","has_lisa_potential","lisa_bonus_amount"],"title":"IsaStatusResponse"},"LabelMerchantsResponse":{"properties":{"status":{"type":"string","title":"Status"},"keys_considered":{"type":"integer","title":"Keys Considered","default":0},"keys_ineligible":{"type":"integer","title":"Keys Ineligible","default":0},"keys_sent":{"type":"integer","title":"Keys Sent","default":0},"keys_labelled":{"type":"integer","title":"Keys Labelled","default":0},"calls":{"type":"integer","title":"Calls","default":0},"cost_gbp":{"type":"number","title":"Cost Gbp","default":0.0},"stopped_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stopped Reason"}},"type":"object","required":["status"],"title":"LabelMerchantsResponse"},"LiveEntryResponse":{"properties":{"id":{"type":"string","title":"Id"},"category":{"type":"string","title":"Category"},"scan_date":{"type":"string","format":"date-time","title":"Scan Date"},"market_summary":{"type":"string","title":"Market Summary"},"best_value_range_low":{"type":"number","title":"Best Value Range Low"},"best_value_range_high":{"type":"number","title":"Best Value Range High"},"ofgem_price_cap_monthly":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ofgem Price Cap Monthly"},"source_urls":{"items":{},"type":"array","title":"Source Urls"},"confidence":{"type":"string","title":"Confidence"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"affiliate_url":{"type":"string","title":"Affiliate Url"},"raw_api_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Raw Api Data"},"data_sources":{"items":{},"type":"array","title":"Data Sources"},"approved_date":{"type":"string","format":"date-time","title":"Approved Date"},"approved_by":{"type":"string","title":"Approved By"},"superseded":{"type":"boolean","title":"Superseded"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","category","scan_date","market_summary","best_value_range_low","best_value_range_high","ofgem_price_cap_monthly","source_urls","confidence","notes","affiliate_url","data_sources","approved_date","approved_by","superseded","created_at"],"title":"LiveEntryResponse"},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"},"device_fingerprint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Device Fingerprint"},"device_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Device Name"}},"type":"object","required":["email","password"],"title":"LoginRequest"},"MarkAllReadResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["success","count"],"title":"MarkAllReadResponse"},"MarkBody":{"properties":{"account_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Account Id"},"new_account":{"anyOf":[{"$ref":"#/components/schemas/NewAccount"},{"type":"null"}]}},"type":"object","title":"MarkBody"},"MarkReadResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"id":{"type":"string","title":"Id"}},"type":"object","required":["success","id"],"title":"MarkReadResponse"},"MarketScanResponse":{"properties":{"status":{"type":"string","title":"Status"},"scan_date":{"type":"string","title":"Scan Date"},"created":{"items":{"type":"string"},"type":"array","title":"Created"},"failed":{"items":{"type":"string"},"type":"array","title":"Failed"},"total_pending":{"type":"integer","title":"Total Pending"}},"type":"object","required":["status","scan_date","created","failed","total_pending"],"title":"MarketScanResponse"},"MarketplaceSection":{"properties":{"bucket":{"type":"string","title":"Bucket"},"title":{"type":"string","title":"Title"},"products":{"items":{"$ref":"#/components/schemas/Product"},"type":"array","title":"Products"}},"type":"object","required":["bucket","title","products"],"title":"MarketplaceSection"},"MarriageAllowanceResponse":{"properties":{"eligible":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Eligible"},"reason":{"type":"string","title":"Reason"},"annual_saving":{"type":"number","title":"Annual Saving"},"backdating_available":{"type":"boolean","title":"Backdating Available"},"backdating_years":{"type":"integer","title":"Backdating Years"},"total_potential_saving":{"type":"number","title":"Total Potential Saving"},"claim_url":{"type":"string","title":"Claim Url"},"both_incomes_detected":{"type":"boolean","title":"Both Incomes Detected"}},"type":"object","required":["eligible","reason","annual_saving","backdating_available","backdating_years","total_potential_saving","claim_url","both_incomes_detected"],"title":"MarriageAllowanceResponse"},"MemoryResponse":{"properties":{"id":{"type":"string","title":"Id"},"memory_type":{"type":"string","title":"Memory Type"},"content":{"type":"string","title":"Content"},"confidence":{"type":"number","title":"Confidence"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"}},"type":"object","required":["id","memory_type","content","confidence","created_at","updated_at"],"title":"MemoryResponse"},"MerchantContext":{"properties":{"merchant":{"type":"string","title":"Merchant"},"total_spend":{"type":"number","title":"Total Spend"},"transaction_count":{"type":"integer","title":"Transaction Count"},"average_transaction":{"type":"number","title":"Average Transaction"},"first_seen":{"type":"string","title":"First Seen"},"last_seen":{"type":"string","title":"Last Seen"},"frequency":{"type":"string","title":"Frequency"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"total_received":{"type":"number","title":"Total Received","default":0.0},"direction":{"type":"string","title":"Direction","default":"out"}},"type":"object","required":["merchant","total_spend","transaction_count","average_transaction","first_seen","last_seen","frequency","category"],"title":"MerchantContext"},"MerchantStat":{"properties":{"name":{"type":"string","title":"Name"},"visits":{"type":"integer","title":"Visits"},"total_spent":{"type":"number","title":"Total Spent"}},"type":"object","required":["name","visits","total_spent"],"title":"MerchantStat"},"MessageResponse":{"properties":{"id":{"type":"string","title":"Id"},"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"},"tokens_used":{"type":"integer","title":"Tokens Used"},"created_at":{"type":"string","title":"Created At"},"tool_calls":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Tool Calls"},"model_used":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Used"},"complexity_detected":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Complexity Detected"},"routing_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Routing Reason"}},"type":"object","required":["id","role","content","tokens_used","created_at"],"title":"MessageResponse"},"MonthPointOut":{"properties":{"month":{"type":"string","title":"Month"},"expenditure":{"type":"number","title":"Expenditure"}},"type":"object","required":["month","expenditure"],"title":"MonthPointOut"},"MonthStat":{"properties":{"month":{"type":"string","title":"Month"},"amount":{"type":"number","title":"Amount"}},"type":"object","required":["month","amount"],"title":"MonthStat"},"MonthlyCategory":{"properties":{"category":{"type":"string","title":"Category"},"total":{"type":"number","title":"Total"}},"type":"object","required":["category","total"],"title":"MonthlyCategory"},"MonthlyPoint":{"properties":{"month":{"type":"string","title":"Month"},"expenditure":{"type":"number","title":"Expenditure"},"income":{"type":"number","title":"Income"},"net":{"type":"number","title":"Net"},"by_pot":{"additionalProperties":{"type":"number"},"type":"object","title":"By Pot"},"by_category":{"items":{"$ref":"#/components/schemas/MonthlyCategory"},"type":"array","title":"By Category"}},"type":"object","required":["month","expenditure","income","net","by_pot","by_category"],"title":"MonthlyPoint","description":"One calendar month of the period.\n\nMonths with no activity are present with zeroes rather than absent —\na chart that silently skips an empty month draws a misleading line."},"MonthlyWrapResponse":{"properties":{"id":{"type":"string","title":"Id"},"month":{"type":"string","title":"Month"},"grade":{"type":"string","title":"Grade"},"cards":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Cards"},"generated_at":{"type":"string","title":"Generated At"}},"type":"object","required":["id","month","grade","cards","generated_at"],"title":"MonthlyWrapResponse"},"MovementOut":{"properties":{"key":{"type":"string","title":"Key"},"label":{"type":"string","title":"Label"},"current":{"type":"number","title":"Current"},"prior":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Prior"},"change_abs":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Abs"},"change_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Pct"},"is_new":{"type":"boolean","title":"Is New"}},"type":"object","required":["key","label","current","prior","change_abs","change_pct","is_new"],"title":"MovementOut"},"NetWorthAccountType":{"type":"string","enum":["current","savings","investment","pension","property","crypto","other_asset","credit_card","loan","mortgage","other_debt"],"title":"NetWorthAccountType"},"NetWorthHistoryPoint":{"properties":{"snapshot_date":{"type":"string","title":"Snapshot Date"},"net_worth":{"type":"number","title":"Net Worth"},"total_assets":{"type":"number","title":"Total Assets"},"total_debts":{"type":"number","title":"Total Debts"}},"type":"object","required":["snapshot_date","net_worth","total_assets","total_debts"],"title":"NetWorthHistoryPoint"},"NetWorthOut":{"properties":{"closing":{"type":"number","title":"Closing"},"total_assets":{"type":"number","title":"Total Assets"},"total_debts":{"type":"number","title":"Total Debts"},"opening":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Opening"},"opening_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Opening Date"},"movement":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Movement"},"comparison_note":{"type":"string","title":"Comparison Note"},"source":{"$ref":"#/components/schemas/SourceNoteOut"}},"type":"object","required":["closing","total_assets","total_debts","opening","opening_date","movement","comparison_note","source"],"title":"NetWorthOut"},"NetWorthSnapshotResponse":{"properties":{"status":{"type":"string","title":"Status"},"users_snapshotted":{"type":"integer","title":"Users Snapshotted"},"errors":{"type":"integer","title":"Errors"}},"type":"object","required":["status","users_snapshotted","errors"],"title":"NetWorthSnapshotResponse"},"NetWorthSummary":{"properties":{"user_id":{"type":"string","title":"User Id"},"total_assets":{"type":"number","title":"Total Assets"},"total_debts":{"type":"number","title":"Total Debts"},"net_worth":{"type":"number","title":"Net Worth"},"accounts":{"items":{"$ref":"#/components/schemas/app__api__net_worth__AccountResponse"},"type":"array","title":"Accounts"},"monthly_change":{"type":"number","title":"Monthly Change"},"percentage_change":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Percentage Change"},"property_estimated_value":{"type":"number","title":"Property Estimated Value","default":0.0},"property_mortgage_balance":{"type":"number","title":"Property Mortgage Balance","default":0.0},"property_equity":{"type":"number","title":"Property Equity","default":0.0}},"type":"object","required":["user_id","total_assets","total_debts","net_worth","accounts","monthly_change","percentage_change"],"title":"NetWorthSummary"},"NewAccount":{"properties":{"provider":{"type":"string","maxLength":100,"minLength":1,"title":"Provider"},"wrapper_type":{"type":"string","title":"Wrapper Type"},"display_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Display Name"},"is_pension":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Pension"}},"type":"object","required":["provider","wrapper_type"],"title":"NewAccount"},"NextYearPotential":{"properties":{"if_save_10_percent":{"type":"number","title":"If Save 10 Percent"},"if_cut_eating_out_half":{"type":"number","title":"If Cut Eating Out Half"},"if_cancel_unused_subs":{"type":"number","title":"If Cancel Unused Subs"},"total_potential":{"type":"number","title":"Total Potential"}},"type":"object","required":["if_save_10_percent","if_cut_eating_out_half","if_cancel_unused_subs","total_potential"],"title":"NextYearPotential"},"NotificationHistoryItem":{"properties":{"id":{"type":"string","title":"Id"},"notification_type":{"type":"string","title":"Notification Type"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"},"sent_at":{"type":"string","format":"date-time","title":"Sent At"},"reference_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reference Key"},"read":{"type":"boolean","title":"Read"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","required":["id","notification_type","title","body","sent_at","reference_key","read"],"title":"NotificationHistoryItem"},"NotificationHistoryResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/NotificationHistoryItem"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["items","total"],"title":"NotificationHistoryResponse"},"NotificationPreferencesResponse":{"properties":{"weekly_briefing":{"type":"boolean","title":"Weekly Briefing"},"daily_insights":{"type":"boolean","title":"Daily Insights"},"weekly_insights":{"type":"boolean","title":"Weekly Insights"},"payday_reminders":{"type":"boolean","title":"Payday Reminders"},"budget_alerts":{"type":"boolean","title":"Budget Alerts"},"challenge_updates":{"type":"boolean","title":"Challenge Updates"},"bill_alerts":{"type":"boolean","title":"Bill Alerts"},"spending_alerts":{"type":"boolean","title":"Spending Alerts"},"streak_reminders":{"type":"boolean","title":"Streak Reminders"},"partner_updates":{"type":"boolean","title":"Partner Updates"},"email_monthly_reports":{"type":"boolean","title":"Email Monthly Reports"},"marketing":{"type":"boolean","title":"Marketing"}},"type":"object","required":["weekly_briefing","daily_insights","weekly_insights","payday_reminders","budget_alerts","challenge_updates","bill_alerts","spending_alerts","streak_reminders","partner_updates","email_monthly_reports","marketing"],"title":"NotificationPreferencesResponse"},"NotificationPreferencesUpdate":{"properties":{"weekly_briefing":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Weekly Briefing"},"daily_insights":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Daily Insights"},"weekly_insights":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Weekly Insights"},"payday_reminders":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Payday Reminders"},"budget_alerts":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Budget Alerts"},"challenge_updates":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Challenge Updates"},"bill_alerts":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Bill Alerts"},"spending_alerts":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Spending Alerts"},"streak_reminders":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Streak Reminders"},"partner_updates":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Partner Updates"},"email_monthly_reports":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Email Monthly Reports"},"marketing":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Marketing"}},"type":"object","title":"NotificationPreferencesUpdate"},"NudgeCopy":{"properties":{"notification_title":{"type":"string","title":"Notification Title","default":""},"notification_body":{"type":"string","title":"Notification Body","default":""},"dashboard_title":{"type":"string","title":"Dashboard Title","default":""},"dashboard_body":{"type":"string","title":"Dashboard Body","default":""},"bills_inline":{"type":"string","title":"Bills Inline","default":""}},"type":"object","title":"NudgeCopy"},"OmittedSection":{"properties":{"section":{"type":"string","title":"Section"},"reason":{"type":"string","title":"Reason"},"scope_required":{"type":"string","title":"Scope Required"}},"type":"object","required":["section","reason","scope_required"],"title":"OmittedSection","description":"A section this grant does not cover. Present so the adviser can see\nthat something is missing BECAUSE OF CONSENT rather than concluding the\nclient has no property."},"OnboardingProfile":{"properties":{"primary_goal":{"anyOf":[{"type":"string","enum":["keep_more","save_up","debt_behind","payday"]},{"type":"null"}],"title":"Primary Goal"},"pay_rhythm":{"anyOf":[{"type":"string","enum":["monthly","four_weekly","weekly","changes"]},{"type":"null"}],"title":"Pay Rhythm"},"money_feeling":{"anyOf":[{"type":"string","enum":["feeling_good","getting_there","hand","a_lot"]},{"type":"null"}],"title":"Money Feeling"},"household":{"anyOf":[{"type":"string","enum":["just_me","partner","bit_of_both"]},{"type":"null"}],"title":"Household"},"focus_area":{"anyOf":[{"type":"string","enum":["subscriptions","eating_out","shopping","before_payday","bills"]},{"type":"null"}],"title":"Focus Area"},"prior_habit":{"anyOf":[{"type":"string","enum":["bank_app","spreadsheet","another_app","in_my_head"]},{"type":"null"}],"title":"Prior Habit"},"contact_preference":{"anyOf":[{"type":"string","enum":["needs_a_look","weekly_summary","app_only"]},{"type":"null"}],"title":"Contact Preference"}},"additionalProperties":false,"type":"object","title":"OnboardingProfile","description":"All seven answers. Every field optional: someone who signs in from\n\"Already have an account?\" and registers later has none, and Settings\nedits one field at a time. Unknown keys are rejected, not stored."},"OnboardingProfileResponse":{"properties":{"profile":{"$ref":"#/components/schemas/OnboardingProfile"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["profile"],"title":"OnboardingProfileResponse"},"OneOffItem":{"properties":{"merchant":{"type":"string","title":"Merchant"},"amount":{"type":"number","title":"Amount"},"date":{"type":"string","title":"Date"},"description":{"type":"string","title":"Description"}},"type":"object","required":["merchant","amount","date","description"],"title":"OneOffItem"},"OpportunitiesResponse":{"properties":{"opportunities":{"items":{"$ref":"#/components/schemas/OpportunityResponse"},"type":"array","title":"Opportunities"},"total_potential_annual_saving":{"type":"number","title":"Total Potential Annual Saving"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["opportunities","total_potential_annual_saving","count"],"title":"OpportunitiesResponse"},"OpportunityResponse":{"properties":{"id":{"type":"string","title":"Id"},"category":{"type":"string","title":"Category"},"merchant":{"type":"string","title":"Merchant"},"monthly_amount":{"type":"number","title":"Monthly Amount"},"months_with_provider":{"type":"integer","title":"Months With Provider"},"estimated_monthly_saving":{"type":"number","title":"Estimated Monthly Saving"},"estimated_annual_saving":{"type":"number","title":"Estimated Annual Saving"},"affiliate_url":{"type":"string","title":"Affiliate Url"},"status":{"type":"string","title":"Status"},"priority":{"type":"string","title":"Priority"},"nudge_copy":{"anyOf":[{"$ref":"#/components/schemas/NudgeCopy"},{"type":"null"}]},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","category","merchant","monthly_amount","months_with_provider","estimated_monthly_saving","estimated_annual_saving","affiliate_url","status","priority"],"title":"OpportunityResponse"},"OverlapItem":{"properties":{"category":{"type":"string","title":"Category"},"category_label":{"type":"string","title":"Category Label"},"subscriptions":{"items":{"type":"string"},"type":"array","title":"Subscriptions"},"amounts":{"items":{"type":"number"},"type":"array","title":"Amounts"},"total_monthly":{"type":"number","title":"Total Monthly"},"recommendation":{"type":"string","title":"Recommendation"},"potential_saving_monthly":{"type":"number","title":"Potential Saving Monthly"},"potential_saving_annual":{"type":"number","title":"Potential Saving Annual"},"affiliate_category":{"type":"string","title":"Affiliate Category"}},"type":"object","required":["category","category_label","subscriptions","amounts","total_monthly","recommendation","potential_saving_monthly","potential_saving_annual","affiliate_category"],"title":"OverlapItem"},"OverpayingInfo":{"properties":{"current_amount":{"type":"number","title":"Current Amount"},"standard_max":{"type":"number","title":"Standard Max"},"excess":{"type":"number","title":"Excess"}},"type":"object","required":["current_amount","standard_max","excess"],"title":"OverpayingInfo"},"OverpaymentRequest":{"properties":{"extra_monthly":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Extra Monthly"}},"type":"object","required":["extra_monthly"],"title":"OverpaymentRequest"},"OverpaymentResponse":{"properties":{"current_monthly_payment":{"type":"number","title":"Current Monthly Payment"},"new_monthly_payment":{"type":"number","title":"New Monthly Payment"},"current_total_cost":{"type":"number","title":"Current Total Cost"},"new_total_cost":{"type":"number","title":"New Total Cost"},"interest_saved":{"type":"number","title":"Interest Saved"},"months_saved":{"type":"integer","title":"Months Saved"},"current_payoff_date":{"type":"string","title":"Current Payoff Date"},"new_payoff_date":{"type":"string","title":"New Payoff Date"},"current_remaining_months":{"type":"integer","title":"Current Remaining Months"},"new_remaining_months":{"type":"integer","title":"New Remaining Months"}},"type":"object","required":["current_monthly_payment","new_monthly_payment","current_total_cost","new_total_cost","interest_saved","months_saved","current_payoff_date","new_payoff_date","current_remaining_months","new_remaining_months"],"title":"OverpaymentResponse"},"OverrideCreate":{"properties":{"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"excluded_from_budgets":{"type":"boolean","title":"Excluded From Budgets","default":false},"is_reimbursable":{"type":"boolean","title":"Is Reimbursable","default":false},"reimbursed":{"type":"boolean","title":"Reimbursed","default":false},"splits":{"anyOf":[{"items":{"$ref":"#/components/schemas/SplitItem"},"type":"array"},{"type":"null"}],"title":"Splits"}},"type":"object","title":"OverrideCreate"},"OverrideDeleteResponse":{"properties":{"transaction_id":{"type":"string","title":"Transaction Id"},"override_removed":{"type":"boolean","title":"Override Removed"},"category_reset":{"type":"boolean","title":"Category Reset"},"merchant_rule_removed":{"type":"boolean","title":"Merchant Rule Removed"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"category_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category Source"}},"type":"object","required":["transaction_id","override_removed","category_reset","merchant_rule_removed","category","category_source"],"title":"OverrideDeleteResponse"},"OverrideResponse":{"properties":{"id":{"type":"string","title":"Id"},"transaction_id":{"type":"string","title":"Transaction Id"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"excluded_from_budgets":{"type":"boolean","title":"Excluded From Budgets"},"is_reimbursable":{"type":"boolean","title":"Is Reimbursable"},"reimbursed":{"type":"boolean","title":"Reimbursed"},"splits":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Splits"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"}},"type":"object","required":["id","transaction_id","notes","excluded_from_budgets","is_reimbursable","reimbursed","splits","created_at","updated_at"],"title":"OverrideResponse"},"OverrideType":{"type":"string","enum":["bill","subscription","habit","not_recurring"],"title":"OverrideType"},"PartnerStatusResponse":{"properties":{"has_partner":{"type":"boolean","title":"Has Partner"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"partner_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partner Name"},"partner_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partner Id"},"connected_since":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connected Since"},"invite_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Code"},"invite_expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Expires At"}},"type":"object","required":["has_partner"],"title":"PartnerStatusResponse"},"PayScheduleBody":{"properties":{"cadence":{"type":"string","enum":["monthly","twice_monthly","weekly","fortnightly","four_weekly","irregular"],"title":"Cadence"},"amount":{"anyOf":[{"type":"number","maximum":1000000.0,"exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d{0,2}0*$"}],"title":"Amount"},"day_of_month":{"anyOf":[{"type":"integer","maximum":31.0,"minimum":1.0},{"type":"null"}],"title":"Day Of Month"},"second_day":{"anyOf":[{"type":"integer","maximum":31.0,"minimum":1.0},{"type":"null"}],"title":"Second Day"},"weekday":{"anyOf":[{"type":"integer","maximum":6.0,"minimum":0.0},{"type":"null"}],"title":"Weekday"},"anchor":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Anchor"},"irregular_frequency":{"anyOf":[{"type":"string","enum":["roughly_monthly","few_times_a_month","varies"]},{"type":"null"}],"title":"Irregular Frequency"},"next_expected":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Next Expected"},"income_kind":{"anyOf":[{"type":"string","enum":["salary","freelancer","student","other"]},{"type":"null"}],"title":"Income Kind"}},"type":"object","required":["cadence","amount"],"title":"PayScheduleBody"},"PayScheduleOut":{"properties":{"cadence":{"type":"string","enum":["monthly","twice_monthly","weekly","fortnightly","four_weekly","irregular"],"title":"Cadence"},"amount":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Amount"},"day_of_month":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Day Of Month"},"second_day":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Second Day"},"weekday":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Weekday"},"anchor":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Anchor"},"irregular_frequency":{"anyOf":[{"type":"string","enum":["roughly_monthly","few_times_a_month","varies"]},{"type":"null"}],"title":"Irregular Frequency"},"next_expected":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Next Expected"},"income_kind":{"anyOf":[{"type":"string","enum":["salary","freelancer","student","other"]},{"type":"null"}],"title":"Income Kind"}},"type":"object","required":["cadence"],"title":"PayScheduleOut"},"PayScheduleResponse":{"properties":{"confirmed":{"anyOf":[{"$ref":"#/components/schemas/PayScheduleOut"},{"type":"null"}]},"confirmed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Confirmed At"},"prefill":{"anyOf":[{"$ref":"#/components/schemas/PayScheduleOut"},{"type":"null"}]},"prefill_source":{"anyOf":[{"type":"string","enum":["onboarding","detection","onboarding+detection"]},{"type":"null"}],"title":"Prefill Source"},"suggestion":{"anyOf":[{"$ref":"#/components/schemas/PaySuggestion"},{"type":"null"}]},"next_payday":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Next Payday"},"days_until_payday":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days Until Payday"},"cycle_start":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Cycle Start"},"cycle_end":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Cycle End"},"cadence_phrase":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cadence Phrase"}},"type":"object","title":"PayScheduleResponse"},"PaySuggestion":{"properties":{"source_name":{"type":"string","title":"Source Name"},"amount":{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$","title":"Amount"},"cadence":{"type":"string","enum":["monthly","twice_monthly","weekly","fortnightly","four_weekly","irregular"],"title":"Cadence"},"occurrences":{"type":"integer","title":"Occurrences"},"last_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Last Date"}},"type":"object","required":["source_name","amount","cadence","occurrences"],"title":"PaySuggestion","description":"What detection noticed — shown as \"we noticed £X from Y, use this?\"."},"PaydayDetectedResponse":{"properties":{"has_targets":{"type":"boolean","title":"Has Targets"},"target_count":{"type":"integer","title":"Target Count"},"message":{"type":"string","title":"Message"}},"type":"object","required":["has_targets","target_count","message"],"title":"PaydayDetectedResponse"},"PaydayPreferencesRequest":{"properties":{"savings_pct":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Savings Pct"},"investments_pct":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Investments Pct"},"bills_pct":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Bills Pct"},"discretionary_pct":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Discretionary Pct"}},"type":"object","required":["savings_pct","investments_pct","bills_pct","discretionary_pct"],"title":"PaydayPreferencesRequest"},"PaydayPreferencesResponse":{"properties":{"savings_pct":{"type":"number","title":"Savings Pct"},"investments_pct":{"type":"number","title":"Investments Pct"},"bills_pct":{"type":"number","title":"Bills Pct"},"discretionary_pct":{"type":"number","title":"Discretionary Pct"},"monthly_income":{"type":"number","title":"Monthly Income"},"allocations":{"items":{"$ref":"#/components/schemas/AllocationBreakdown"},"type":"array","title":"Allocations"}},"type":"object","required":["savings_pct","investments_pct","bills_pct","discretionary_pct","monthly_income","allocations"],"title":"PaydayPreferencesResponse"},"PaydayPreview":{"properties":{"detected_payday":{"type":"integer","title":"Detected Payday"},"next_payday":{"type":"string","title":"Next Payday"},"days_until_payday":{"type":"integer","title":"Days Until Payday"},"monthly_income":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Monthly Income"},"total_allocated":{"type":"number","title":"Total Allocated"},"remaining_after_rules":{"type":"number","title":"Remaining After Rules"},"timeline":{"items":{"$ref":"#/components/schemas/TimelineEvent"},"type":"array","title":"Timeline"},"rules":{"items":{"$ref":"#/components/schemas/PaydayRule"},"type":"array","title":"Rules"},"suggestions":{"items":{"$ref":"#/components/schemas/SmartSuggestion"},"type":"array","title":"Suggestions"},"has_data":{"type":"boolean","title":"Has Data"},"salary_detection_status":{"type":"string","title":"Salary Detection Status","default":"detected"},"income_stale":{"type":"boolean","title":"Income Stale","default":false},"one_off_income_this_cycle":{"type":"number","title":"One Off Income This Cycle","default":0.0},"incoming_this_cycle":{"type":"number","title":"Incoming This Cycle","default":0.0}},"type":"object","required":["detected_payday","next_payday","days_until_payday","monthly_income","total_allocated","remaining_after_rules","timeline","rules","suggestions","has_data"],"title":"PaydayPreview"},"PaydayRule":{"properties":{"id":{"type":"string","title":"Id"},"type":{"type":"string","title":"Type"},"amount":{"type":"number","title":"Amount"},"timing":{"type":"string","title":"Timing"},"timing_label":{"type":"string","title":"Timing Label"},"active":{"type":"boolean","title":"Active"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"target_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Id"},"target_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Label"},"virtual_budget_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Virtual Budget Category"},"pot_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pot Category"},"goal_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Goal Id"},"goal_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Goal Name"}},"type":"object","required":["id","type","amount","timing","timing_label","active"],"title":"PaydayRule"},"PaydayRuleItem":{"properties":{"rule_type":{"type":"string","title":"Rule Type"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"amount":{"type":"number","title":"Amount"},"timing":{"type":"string","title":"Timing"}},"type":"object","required":["rule_type","label","amount","timing"],"title":"PaydayRuleItem"},"PaydayRulePatch":{"properties":{"amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Amount"},"active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Active"},"timing":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timing"},"timing_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timing Label"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"target_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Id"},"target_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Label"}},"type":"object","title":"PaydayRulePatch","description":"Partial update for a single rule. Every field is optional; only those\nexplicitly present in the request body are applied."},"PaydayStatusResponse":{"properties":{"detected_payday":{"type":"integer","title":"Detected Payday"},"next_payday":{"type":"string","title":"Next Payday"},"days_until_payday":{"type":"integer","title":"Days Until Payday"},"last_payday":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Payday"},"monthly_income":{"type":"number","title":"Monthly Income"},"is_payday_today":{"type":"boolean","title":"Is Payday Today"},"pay_confirmed":{"type":"boolean","title":"Pay Confirmed","default":false},"pay_cadence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pay Cadence"},"pay_amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pay Amount"},"next_payday_known":{"type":"boolean","title":"Next Payday Known","default":true},"cycle_start":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cycle Start"},"cycle_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cycle End"}},"type":"object","required":["detected_payday","next_payday","days_until_payday","last_payday","monthly_income","is_payday_today"],"title":"PaydayStatusResponse"},"PaydaySuggestionResponse":{"properties":{"summary":{"type":"string","title":"Summary"},"next_payday":{"type":"string","title":"Next Payday"},"monthly_income":{"type":"number","title":"Monthly Income"},"allocations":{"items":{"$ref":"#/components/schemas/AllocationBreakdown"},"type":"array","title":"Allocations"},"total_allocated":{"type":"number","title":"Total Allocated"},"remaining":{"type":"number","title":"Remaining"},"accepted":{"type":"boolean","title":"Accepted","default":false},"cycle_review":{"anyOf":[{"$ref":"#/components/schemas/CycleReview"},{"type":"null"}]},"goal_split":{"items":{"$ref":"#/components/schemas/GoalSplit"},"type":"array","title":"Goal Split","default":[]},"goals_unplanned":{"items":{"$ref":"#/components/schemas/GoalUnplanned"},"type":"array","title":"Goals Unplanned","default":[]},"buffer":{"anyOf":[{"$ref":"#/components/schemas/CoachBuffer"},{"type":"null"}]},"income_stale":{"type":"boolean","title":"Income Stale","default":false},"one_off_income_this_cycle":{"type":"number","title":"One Off Income This Cycle","default":0.0},"incoming_this_cycle":{"type":"number","title":"Incoming This Cycle","default":0.0},"usual_spending":{"type":"number","title":"Usual Spending","default":0.0},"bills_detail":{"anyOf":[{"$ref":"#/components/schemas/BillsDetail"},{"type":"null"}]}},"type":"object","required":["summary","next_payday","monthly_income","allocations","total_allocated","remaining"],"title":"PaydaySuggestionResponse"},"PaymentHistoryItem":{"properties":{"id":{"type":"string","title":"Id"},"payment_id":{"type":"string","title":"Payment Id"},"target_label":{"type":"string","title":"Target Label"},"amount":{"type":"number","title":"Amount"},"currency":{"type":"string","title":"Currency"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","title":"Created At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["id","payment_id","target_label","amount","currency","status","created_at"],"title":"PaymentHistoryItem"},"PaymentHistoryResponse":{"properties":{"payments":{"items":{"$ref":"#/components/schemas/PaymentHistoryItem"},"type":"array","title":"Payments"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["payments","total"],"title":"PaymentHistoryResponse"},"PaymentResponse":{"properties":{"payment_id":{"type":"string","title":"Payment Id"},"consent_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consent Url"},"amount":{"type":"number","title":"Amount"},"target_label":{"type":"string","title":"Target Label"},"status":{"type":"string","title":"Status"}},"type":"object","required":["payment_id","amount","target_label","status"],"title":"PaymentResponse"},"PendingBankAuthResponse":{"properties":{"status":{"type":"string","title":"Status"},"completed":{"type":"integer","title":"Completed"},"still_pending":{"type":"integer","title":"Still Pending"},"expired":{"type":"integer","title":"Expired"},"errors":{"type":"integer","title":"Errors"},"first_sync_due":{"type":"integer","title":"First Sync Due","default":0},"first_sync_attempted":{"type":"integer","title":"First Sync Attempted","default":0}},"type":"object","required":["status","completed","still_pending","expired","errors"],"title":"PendingBankAuthResponse"},"PendingEntryResponse":{"properties":{"id":{"type":"string","title":"Id"},"category":{"type":"string","title":"Category"},"scan_date":{"type":"string","format":"date-time","title":"Scan Date"},"market_summary":{"type":"string","title":"Market Summary"},"best_value_range_low":{"type":"number","title":"Best Value Range Low"},"best_value_range_high":{"type":"number","title":"Best Value Range High"},"ofgem_price_cap_monthly":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ofgem Price Cap Monthly"},"source_urls":{"items":{},"type":"array","title":"Source Urls"},"confidence":{"type":"string","title":"Confidence"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"affiliate_url":{"type":"string","title":"Affiliate Url"},"status":{"type":"string","title":"Status"},"rejection_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rejection Reason"},"raw_api_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Raw Api Data"},"data_sources":{"items":{},"type":"array","title":"Data Sources"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","category","scan_date","market_summary","best_value_range_low","best_value_range_high","ofgem_price_cap_monthly","source_urls","confidence","notes","affiliate_url","status","data_sources","created_at"],"title":"PendingEntryResponse"},"PensionOptimisationResponse":{"properties":{"current_band":{"type":"string","title":"Current Band"},"annual_income":{"type":"number","title":"Annual Income"},"detected_monthly_pension":{"type":"number","title":"Detected Monthly Pension"},"detected_annual_pension":{"type":"number","title":"Detected Annual Pension"},"optimal_contribution_to_stay_in_band":{"type":"number","title":"Optimal Contribution To Stay In Band"},"tax_saved_by_optimal":{"type":"number","title":"Tax Saved By Optimal"},"effective_cost_per_100":{"type":"number","title":"Effective Cost Per 100"},"salary_sacrifice_ni_saving":{"type":"number","title":"Salary Sacrifice Ni Saving"},"employer_match_potential":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Employer Match Potential"},"pension_allowance_used":{"type":"number","title":"Pension Allowance Used"},"pension_allowance_remaining":{"type":"number","title":"Pension Allowance Remaining"},"personal_allowance_restoration":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Personal Allowance Restoration"},"personal_allowance_restoration_saving":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Personal Allowance Restoration Saving"},"suggested_allocation_amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Suggested Allocation Amount"}},"type":"object","required":["current_band","annual_income","detected_monthly_pension","detected_annual_pension","optimal_contribution_to_stay_in_band","tax_saved_by_optimal","effective_cost_per_100","salary_sacrifice_ni_saving","employer_match_potential","pension_allowance_used","pension_allowance_remaining","personal_allowance_restoration","personal_allowance_restoration_saving"],"title":"PensionOptimisationResponse"},"PerCategorySaving":{"properties":{"category":{"type":"string","title":"Category"},"annual_saving":{"type":"number","title":"Annual Saving"},"switch_count":{"type":"integer","title":"Switch Count"}},"type":"object","required":["category","annual_saving","switch_count"],"title":"PerCategorySaving"},"PeriodOut":{"properties":{"start":{"type":"string","format":"date","title":"Start"},"end":{"type":"string","format":"date","title":"End"},"label":{"type":"string","title":"Label"},"months":{"type":"integer","title":"Months"}},"type":"object","required":["start","end","label","months"],"title":"PeriodOut"},"PmiInvalidateResponse":{"properties":{"uprn":{"type":"string","title":"Uprn"},"cleared":{"type":"boolean","title":"Cleared"}},"type":"object","required":["uprn","cleared"],"title":"PmiInvalidateResponse"},"PmiRefreshResponse":{"properties":{"status":{"type":"string","title":"Status"},"uprns_checked":{"type":"integer","title":"Uprns Checked"},"refreshed":{"type":"integer","title":"Refreshed"},"credit_capped":{"type":"boolean","title":"Credit Capped"},"errors":{"type":"integer","title":"Errors"},"verdicts_refreshed":{"type":"integer","title":"Verdicts Refreshed","default":0}},"type":"object","required":["status","uprns_checked","refreshed","credit_capped","errors"],"title":"PmiRefreshResponse"},"PossibleItem":{"properties":{"merchant":{"type":"string","title":"Merchant"},"section":{"type":"string","title":"Section"},"category":{"type":"string","title":"Category"},"monthly_cost":{"type":"number","title":"Monthly Cost"},"interval_type":{"type":"string","title":"Interval Type"},"charge_count":{"type":"integer","title":"Charge Count"},"last_charge_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Charge Date"},"next_expected_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Expected Date"},"reason":{"type":"string","title":"Reason","default":"two_occurrences"}},"type":"object","required":["merchant","section","category","monthly_cost","interval_type","charge_count"],"title":"PossibleItem","description":"Stage A rule 3: a bill/subscription seen fewer than three times on\ncadence. Shown separately, never counted in the totals."},"PotsSummaryResponse":{"properties":{"pots":{"items":{"$ref":"#/components/schemas/app__api__pots__PotSummary"},"type":"array","title":"Pots"},"total":{"type":"number","title":"Total"},"period":{"type":"string","title":"Period"},"has_data":{"type":"boolean","title":"Has Data","default":false}},"type":"object","required":["pots","total","period"],"title":"PotsSummaryResponse"},"PresetScenario":{"properties":{"type":{"type":"string","title":"Type"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"icon":{"type":"string","title":"Icon"},"current_monthly":{"type":"number","title":"Current Monthly"},"default_change":{"type":"number","title":"Default Change"},"change_unit":{"type":"string","title":"Change Unit"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},"type":"object","required":["type","title","description","icon","current_monthly","default_change","change_unit"],"title":"PresetScenario"},"PresetsResponse":{"properties":{"presets":{"items":{"$ref":"#/components/schemas/PresetScenario"},"type":"array","title":"Presets"},"has_data":{"type":"boolean","title":"Has Data"}},"type":"object","required":["presets","has_data"],"title":"PresetsResponse"},"PriceChange":{"properties":{"previous_amount":{"type":"number","title":"Previous Amount"},"current_amount":{"type":"number","title":"Current Amount"},"change_amount":{"type":"number","title":"Change Amount"},"change_percentage":{"type":"number","title":"Change Percentage"}},"type":"object","required":["previous_amount","current_amount","change_amount","change_percentage"],"title":"PriceChange"},"PriceIncrease":{"properties":{"alert_id":{"type":"string","title":"Alert Id"},"merchant":{"type":"string","title":"Merchant"},"previous_amount":{"type":"number","title":"Previous Amount"},"new_amount":{"type":"number","title":"New Amount"},"increase_amount":{"type":"number","title":"Increase Amount"},"increase_percentage":{"type":"number","title":"Increase Percentage"},"annual_impact":{"type":"number","title":"Annual Impact"},"first_detected":{"type":"string","title":"First Detected"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},"type":"object","required":["alert_id","merchant","previous_amount","new_amount","increase_amount","increase_percentage","annual_impact","first_detected","category"],"title":"PriceIncrease"},"Product":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"bucket":{"type":"string","title":"Bucket"},"provider":{"type":"string","title":"Provider"},"selling_point":{"type":"string","title":"Selling Point"},"description":{"type":"string","title":"Description"},"rating":{"type":"number","title":"Rating"},"cta_text":{"type":"string","title":"Cta Text"},"affiliate_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Affiliate Url"}},"type":"object","required":["id","name","bucket","provider","selling_point","description","rating","cta_text"],"title":"Product"},"ProgressUpdate":{"properties":{"current_amount":{"type":"number","title":"Current Amount"}},"type":"object","required":["current_amount"],"title":"ProgressUpdate"},"Projection":{"properties":{"years":{"type":"integer","title":"Years"},"invested_total":{"type":"number","title":"Invested Total"},"with_growth":{"type":"number","title":"With Growth"},"growth_earned":{"type":"number","title":"Growth Earned"}},"type":"object","required":["years","invested_total","with_growth","growth_earned"],"title":"Projection"},"ProjectionResponse":{"properties":{"plan_id":{"type":"string","title":"Plan Id"},"plan_name":{"type":"string","title":"Plan Name"},"current_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Value"},"monthly_contribution":{"type":"number","title":"Monthly Contribution"},"time_horizon_years":{"type":"integer","title":"Time Horizon Years"},"scenarios":{"items":{"$ref":"#/components/schemas/ProjectionScenario"},"type":"array","title":"Scenarios"},"needs_valuation":{"type":"boolean","title":"Needs Valuation","default":false},"valuation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Valuation Date"},"account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Id"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["plan_id","plan_name","current_value","monthly_contribution","time_horizon_years","scenarios"],"title":"ProjectionResponse"},"ProjectionScenario":{"properties":{"rate_pct":{"type":"number","title":"Rate Pct"},"rate_label":{"type":"string","title":"Rate Label"},"final_value":{"type":"number","title":"Final Value"},"total_contributed":{"type":"number","title":"Total Contributed"},"total_growth":{"type":"number","title":"Total Growth"},"final_value_after_fees":{"type":"number","title":"Final Value After Fees"},"fee_drag":{"type":"number","title":"Fee Drag"}},"type":"object","required":["rate_pct","rate_label","final_value","total_contributed","total_growth","final_value_after_fees","fee_drag"],"title":"ProjectionScenario"},"PropertyCreate":{"properties":{"postcode":{"type":"string","maxLength":10,"minLength":5,"title":"Postcode"},"property_type":{"$ref":"#/components/schemas/PropertyType"},"purchase_price":{"anyOf":[{"type":"number","maximum":100000000.0,"exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Purchase Price"},"purchase_month":{"type":"string","format":"date","title":"Purchase Month"},"nickname":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Nickname"},"mortgage_balance":{"anyOf":[{"type":"number","maximum":100000000.0,"minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Mortgage Balance"},"uprn":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Uprn"}},"type":"object","required":["postcode","property_type","purchase_price","purchase_month"],"title":"PropertyCreate"},"PropertyListResponse":{"properties":{"properties":{"items":{"$ref":"#/components/schemas/PropertyResponse"},"type":"array","title":"Properties"},"attribution":{"type":"string","title":"Attribution"}},"type":"object","required":["properties","attribution"],"title":"PropertyListResponse"},"PropertyOut":{"properties":{"properties":{"items":{"$ref":"#/components/schemas/PropertyPositionOut"},"type":"array","title":"Properties"},"combined_estimated_value":{"type":"number","title":"Combined Estimated Value"},"combined_mortgage_balance":{"type":"number","title":"Combined Mortgage Balance"},"combined_equity":{"type":"number","title":"Combined Equity"},"source":{"$ref":"#/components/schemas/SourceNoteOut"}},"type":"object","required":["properties","combined_estimated_value","combined_mortgage_balance","combined_equity","source"],"title":"PropertyOut"},"PropertyPositionOut":{"properties":{"label":{"type":"string","title":"Label"},"postcode":{"type":"string","title":"Postcode"},"property_type":{"type":"string","title":"Property Type"},"purchase_price":{"type":"number","title":"Purchase Price"},"purchase_month":{"type":"string","format":"date","title":"Purchase Month"},"estimated_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Estimated Value"},"mortgage_balance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Mortgage Balance"},"equity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Equity"},"valuation_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Valuation Source"},"valuation_as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Valuation As Of"},"valuation_confidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Valuation Confidence"},"is_estimate":{"type":"boolean","title":"Is Estimate"}},"type":"object","required":["label","postcode","property_type","purchase_price","purchase_month","estimated_value","mortgage_balance","equity","valuation_source","valuation_as_of","valuation_confidence","is_estimate"],"title":"PropertyPositionOut"},"PropertyResponse":{"properties":{"id":{"type":"string","title":"Id"},"nickname":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nickname"},"postcode":{"type":"string","title":"Postcode"},"admin_district":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Admin District"},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region"},"property_type":{"type":"string","title":"Property Type"},"purchase_price":{"type":"number","title":"Purchase Price"},"purchase_month":{"type":"string","title":"Purchase Month"},"mortgage_balance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Mortgage Balance"},"estimated_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Estimated Value"},"equity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Equity"},"index_month_used":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Index Month Used"},"location_level_used":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location Level Used"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","title":"Created At"},"attribution":{"type":"string","title":"Attribution"},"valuation_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Valuation Source"},"valuation_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Valuation Date"},"valuation_confidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Valuation Confidence"},"valuation_lower_bound":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Valuation Lower Bound"},"valuation_upper_bound":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Valuation Upper Bound"},"manual_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Manual Value"},"uprn":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uprn"},"value_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value Label"},"needs_value":{"type":"boolean","title":"Needs Value","default":false},"pmi_verdict":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pmi Verdict"},"pmi_rejected_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pmi Rejected Reason"},"pmi_checked_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pmi Checked At"},"pmi_estimate_seen":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pmi Estimate Seen"},"pmi_estimate_confidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pmi Estimate Confidence"},"pmi_estimate_lower_bound":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pmi Estimate Lower Bound"},"pmi_estimate_upper_bound":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Pmi Estimate Upper Bound"}},"type":"object","required":["id","nickname","postcode","admin_district","region","property_type","purchase_price","purchase_month","mortgage_balance","estimated_value","equity","index_month_used","location_level_used","is_active","created_at","attribution"],"title":"PropertyResponse"},"PropertyType":{"type":"string","enum":["detached","semi_detached","terraced","flat"],"title":"PropertyType"},"PropertyUpdate":{"properties":{"nickname":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Nickname"},"postcode":{"anyOf":[{"type":"string","maxLength":10,"minLength":5},{"type":"null"}],"title":"Postcode"},"purchase_price":{"anyOf":[{"type":"number","maximum":100000000.0,"exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Purchase Price"},"mortgage_balance":{"anyOf":[{"type":"number","maximum":100000000.0,"minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Mortgage Balance"},"uprn":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Uprn"},"manual_value":{"anyOf":[{"type":"number","maximum":100000000.0,"exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Manual Value"},"clear_manual_value":{"type":"boolean","title":"Clear Manual Value","default":false}},"type":"object","title":"PropertyUpdate"},"PushTokenRequest":{"properties":{"push_token":{"type":"string","title":"Push Token"}},"type":"object","required":["push_token"],"title":"PushTokenRequest"},"PushTokenResponse":{"properties":{"success":{"type":"boolean","title":"Success"}},"type":"object","required":["success"],"title":"PushTokenResponse"},"QuizListItem":{"properties":{"topic":{"type":"string","title":"Topic"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"icon":{"type":"string","title":"Icon"},"question_count":{"type":"integer","title":"Question Count"},"completed":{"type":"boolean","title":"Completed"},"best_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Best Score"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["topic","title","description","icon","question_count","completed"],"title":"QuizListItem"},"QuizQuestion":{"properties":{"index":{"type":"integer","title":"Index"},"question":{"type":"string","title":"Question"},"options":{"items":{"type":"string"},"type":"array","title":"Options"}},"type":"object","required":["index","question","options"],"title":"QuizQuestion"},"QuizQuestionsResponse":{"properties":{"topic":{"type":"string","title":"Topic"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"questions":{"items":{"$ref":"#/components/schemas/QuizQuestion"},"type":"array","title":"Questions"}},"type":"object","required":["topic","title","description","questions"],"title":"QuizQuestionsResponse"},"QuizResultItem":{"properties":{"question":{"type":"string","title":"Question"},"your_answer":{"type":"integer","title":"Your Answer"},"correct_answer":{"type":"integer","title":"Correct Answer"},"correct":{"type":"boolean","title":"Correct"},"explanation":{"type":"string","title":"Explanation"}},"type":"object","required":["question","your_answer","correct_answer","correct","explanation"],"title":"QuizResultItem"},"QuizSubmitRequest":{"properties":{"answers":{"items":{"type":"integer"},"type":"array","title":"Answers"}},"type":"object","required":["answers"],"title":"QuizSubmitRequest"},"QuizSubmitResponse":{"properties":{"topic":{"type":"string","title":"Topic"},"score":{"type":"integer","title":"Score"},"total":{"type":"integer","title":"Total"},"percentage":{"type":"integer","title":"Percentage"},"results":{"items":{"$ref":"#/components/schemas/QuizResultItem"},"type":"array","title":"Results"},"xp_awarded":{"type":"integer","title":"Xp Awarded"},"perfect_score":{"type":"boolean","title":"Perfect Score"}},"type":"object","required":["topic","score","total","percentage","results","xp_awarded","perfect_score"],"title":"QuizSubmitResponse"},"RaiseBreakdown":{"properties":{"gross":{"type":"number","title":"Gross"},"tax_on_raise":{"type":"number","title":"Tax On Raise"},"ni_on_raise":{"type":"number","title":"Ni On Raise"},"net_raise":{"type":"number","title":"Net Raise"},"monthly_increase":{"type":"number","title":"Monthly Increase"},"effective_rate":{"type":"number","title":"Effective Rate"}},"type":"object","required":["gross","tax_on_raise","ni_on_raise","net_raise","monthly_increase","effective_rate"],"title":"RaiseBreakdown"},"RaiseRequest":{"properties":{"current_salary":{"type":"number","exclusiveMinimum":0.0,"title":"Current Salary"},"raise_amount":{"type":"number","exclusiveMinimum":0.0,"title":"Raise Amount"},"raise_type":{"type":"string","title":"Raise Type","default":"amount"}},"type":"object","required":["current_salary","raise_amount"],"title":"RaiseRequest"},"RaiseResponse":{"properties":{"current":{"$ref":"#/components/schemas/TaxBreakdown"},"new":{"$ref":"#/components/schemas/TaxBreakdown"},"raise_detail":{"$ref":"#/components/schemas/RaiseBreakdown"},"crosses_bracket":{"type":"boolean","title":"Crosses Bracket"},"bracket_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bracket Message"},"projections":{"items":{"$ref":"#/components/schemas/Projection"},"type":"array","title":"Projections"},"allocation":{"$ref":"#/components/schemas/AllocationSuggestion"}},"type":"object","required":["current","new","raise_detail","crosses_bracket","bracket_message","projections","allocation"],"title":"RaiseResponse"},"ReadinessResponse":{"properties":{"state":{"type":"string","title":"State"},"transaction_count":{"type":"integer","title":"Transaction Count"},"first_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Date"},"last_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Date"},"connections_active":{"type":"integer","title":"Connections Active"},"connections_awaiting":{"type":"integer","title":"Connections Awaiting"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["state","transaction_count","connections_active","connections_awaiting"],"title":"ReadinessResponse","description":"What Ask IQ can see right now (EQ-65). `message` is the exact reply a\nquestion would get while `state` is not ready, so the client can show it\nbefore the user types."},"RecapListItem":{"properties":{"id":{"type":"string","title":"Id"},"month":{"type":"string","title":"Month"},"grade":{"type":"string","title":"Grade"},"generated_at":{"type":"string","title":"Generated At"}},"type":"object","required":["id","month","grade","generated_at"],"title":"RecapListItem"},"RecapResponse":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"month":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Month"},"sections":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Sections"},"grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grade"},"generated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Generated At"},"available":{"type":"boolean","title":"Available","default":true}},"type":"object","required":["id","month","sections","grade","generated_at"],"title":"RecapResponse"},"RecategoriseRequest":{"properties":{"category":{"type":"string","title":"Category"}},"type":"object","required":["category"],"title":"RecategoriseRequest"},"RecategoriseResponse":{"properties":{"transaction_id":{"type":"string","title":"Transaction Id"},"old_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Old Category"},"new_category":{"type":"string","title":"New Category"},"user_rule_conflict":{"type":"boolean","title":"User Rule Conflict"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["transaction_id","old_category","new_category","user_rule_conflict","note"],"title":"RecategoriseResponse"},"ReclassifyResponse":{"properties":{"reclassified":{"type":"integer","title":"Reclassified"},"ai_reclassified":{"type":"integer","title":"Ai Reclassified"},"total_general":{"type":"integer","title":"Total General"}},"type":"object","required":["reclassified","ai_reclassified","total_general"],"title":"ReclassifyResponse"},"RecommendationEntry":{"properties":{"name":{"type":"string","title":"Name"},"amount":{"type":"number","title":"Amount"}},"type":"object","required":["name","amount"],"title":"RecommendationEntry"},"RecurringIncome":{"properties":{"source":{"type":"string","title":"Source"},"average_amount":{"type":"number","title":"Average Amount"},"typical_day":{"type":"integer","title":"Typical Day"},"occurrences":{"type":"integer","title":"Occurrences"}},"type":"object","required":["source","average_amount","typical_day","occurrences"],"title":"RecurringIncome"},"RecurringMerchantMatch":{"properties":{"merchant":{"type":"string","title":"Merchant"},"count":{"type":"integer","title":"Count"},"median_amount":{"type":"number","title":"Median Amount"},"last_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Date"},"suggested_frequency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suggested Frequency"}},"type":"object","required":["merchant","count","median_amount","last_date","suggested_frequency"],"title":"RecurringMerchantMatch","description":"A merchant from the user's own transactions, for \"add a bill\"."},"RecurringPreferenceRequest":{"properties":{"merchant_name":{"type":"string","title":"Merchant Name"},"override_type":{"$ref":"#/components/schemas/OverrideType"},"amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Amount"},"frequency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Frequency"},"source":{"type":"string","title":"Source","default":"detected"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"},"surface":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Surface"}},"type":"object","required":["merchant_name","override_type"],"title":"RecurringPreferenceRequest"},"RecurringPreferenceResponse":{"properties":{"id":{"type":"string","title":"Id"},"merchant_name":{"type":"string","title":"Merchant Name"},"override_type":{"type":"string","title":"Override Type"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"},"amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Amount"},"frequency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Frequency"},"source":{"type":"string","title":"Source","default":"detected"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"}},"type":"object","required":["id","merchant_name","override_type","created_at","updated_at"],"title":"RecurringPreferenceResponse"},"RecurringSummaryResponse":{},"RecurringSummaryTotals":{"properties":{"bills_monthly":{"type":"number","title":"Bills Monthly"},"subscriptions_monthly":{"type":"number","title":"Subscriptions Monthly"},"habits_monthly":{"type":"number","title":"Habits Monthly"},"total_monthly":{"type":"number","title":"Total Monthly"},"potential_savings_annual":{"type":"number","title":"Potential Savings Annual"}},"type":"object","required":["bills_monthly","subscriptions_monthly","habits_monthly","total_monthly","potential_savings_annual"],"title":"RecurringSummaryTotals"},"RedeemResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"},"referrer_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Name"}},"type":"object","required":["success","message"],"title":"RedeemResponse"},"ReferralCodeResponse":{"properties":{"referral_code":{"type":"string","title":"Referral Code"}},"type":"object","required":["referral_code"],"title":"ReferralCodeResponse"},"ReferralDashboard":{"properties":{"referral_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referral Code"},"total_invited":{"type":"integer","title":"Total Invited"},"total_signed_up":{"type":"integer","title":"Total Signed Up"},"total_rewarded":{"type":"integer","title":"Total Rewarded"},"premium_months_earned":{"type":"integer","title":"Premium Months Earned"},"has_permanent_premium":{"type":"boolean","title":"Has Permanent Premium"},"referrals":{"items":{"$ref":"#/components/schemas/ReferralItem"},"type":"array","title":"Referrals"}},"type":"object","required":["referral_code","total_invited","total_signed_up","total_rewarded","premium_months_earned","has_permanent_premium","referrals"],"title":"ReferralDashboard"},"ReferralItem":{"properties":{"id":{"type":"string","title":"Id"},"referred_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referred Email"},"referred_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referred Name"},"status":{"type":"string","title":"Status"},"reward_months_earned":{"type":"integer","title":"Reward Months Earned"},"created_at":{"type":"string","title":"Created At"},"redeemed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Redeemed At"},"rewarded_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rewarded At"}},"type":"object","required":["id","referred_email","status","reward_months_earned","created_at"],"title":"ReferralItem"},"ReferralStatsResponse":{"properties":{"total_referrals":{"type":"integer","title":"Total Referrals"},"successful_referrals":{"type":"integer","title":"Successful Referrals"},"rewards_earned":{"type":"integer","title":"Rewards Earned"},"pending_rewards":{"type":"integer","title":"Pending Rewards"},"remaining_slots":{"type":"integer","title":"Remaining Slots"},"referral_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referral Code"}},"type":"object","required":["total_referrals","successful_referrals","rewards_earned","pending_rewards","remaining_slots","referral_code"],"title":"ReferralStatsResponse"},"RefreshRequest":{"properties":{"refresh_token":{"type":"string","title":"Refresh Token"}},"type":"object","required":["refresh_token"],"title":"RefreshRequest"},"RegisterRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"monthly_income":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Monthly Income"},"referral_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referral Code"},"ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref"}},"type":"object","required":["email","password"],"title":"RegisterRequest"},"ReimbursableItem":{"properties":{"transaction_id":{"type":"string","title":"Transaction Id"},"date":{"type":"string","title":"Date"},"description":{"type":"string","title":"Description"},"amount":{"type":"number","title":"Amount"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"merchant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Merchant Name"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["transaction_id","date","description","amount","category","merchant_name","notes"],"title":"ReimbursableItem"},"ReimbursablesResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ReimbursableItem"},"type":"array","title":"Items"},"total_owed":{"type":"number","title":"Total Owed"}},"type":"object","required":["items","total_owed"],"title":"ReimbursablesResponse"},"RejectRequest":{"properties":{"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","title":"RejectRequest"},"RemoveAccountResponse":{"properties":{"connection_id":{"type":"string","title":"Connection Id"},"status":{"type":"string","title":"Status"},"removed_at":{"type":"string","title":"Removed At"},"transactions_preserved":{"type":"boolean","title":"Transactions Preserved"},"consent_still_active":{"type":"boolean","title":"Consent Still Active"},"remaining_accounts_at_bank":{"type":"integer","title":"Remaining Accounts At Bank"}},"type":"object","required":["connection_id","status","removed_at","transactions_preserved","consent_still_active","remaining_accounts_at_bank"],"title":"RemoveAccountResponse"},"RenewalInfo":{"properties":{"approaching_renewal":{"type":"boolean","title":"Approaching Renewal"},"estimated_renewal_date":{"type":"string","title":"Estimated Renewal Date"},"months_active":{"type":"integer","title":"Months Active"}},"type":"object","required":["approaching_renewal","estimated_renewal_date","months_active"],"title":"RenewalInfo"},"ResetIQQuotaBody":{"properties":{"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"}},"type":"object","title":"ResetIQQuotaBody"},"ResetPasswordRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"code":{"type":"string","maxLength":6,"minLength":6,"pattern":"^\\d{6}$","title":"Code"},"new_password":{"type":"string","maxLength":128,"minLength":8,"title":"New Password"}},"type":"object","required":["email","code","new_password"],"title":"ResetPasswordRequest"},"RestoreAccountResponse":{"properties":{"connection_id":{"type":"string","title":"Connection Id"},"status":{"type":"string","title":"Status"},"restored_at":{"type":"string","title":"Restored At"}},"type":"object","required":["connection_id","status","restored_at"],"title":"RestoreAccountResponse"},"RetryImportResponse":{"properties":{"connection_id":{"type":"string","title":"Connection Id"},"status":{"type":"string","title":"Status"},"last_sync_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Sync Status"},"message":{"type":"string","title":"Message"}},"type":"object","required":["connection_id","status","message"],"title":"RetryImportResponse"},"RevenueCatIdRequest":{"properties":{"revenuecat_user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revenuecat User Id"}},"type":"object","title":"RevenueCatIdRequest"},"ReviewHabit":{"properties":{"habit_key":{"type":"string","title":"Habit Key"},"display":{"type":"string","title":"Display"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"hits_per_week":{"type":"number","title":"Hits Per Week"},"weeks_active":{"type":"integer","title":"Weeks Active"},"monthly_spend":{"type":"number","title":"Monthly Spend"},"confidence":{"type":"number","title":"Confidence"},"evidence":{"type":"string","title":"Evidence"},"correction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Correction"}},"type":"object","required":["habit_key","display","hits_per_week","weeks_active","monthly_spend","confidence","evidence"],"title":"ReviewHabit"},"ReviewResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"has_run":{"type":"boolean","title":"Has Run"},"computed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Computed At"},"top_bills":{"items":{"$ref":"#/components/schemas/ReviewStream"},"type":"array","title":"Top Bills","default":[]},"streams":{"items":{"$ref":"#/components/schemas/ReviewStream"},"type":"array","title":"Streams","default":[]},"habits":{"items":{"$ref":"#/components/schemas/ReviewHabit"},"type":"array","title":"Habits","default":[]},"trait":{"anyOf":[{"$ref":"#/components/schemas/ReviewTrait"},{"type":"null"}]},"corrections":{"items":{"$ref":"#/components/schemas/CorrectionResponse"},"type":"array","title":"Corrections","default":[]}},"type":"object","required":["enabled","has_run"],"title":"ReviewResponse"},"ReviewStream":{"properties":{"stream_key":{"type":"string","title":"Stream Key"},"display":{"type":"string","title":"Display"},"state":{"type":"string","title":"State"},"kind":{"type":"string","title":"Kind"},"scheme":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scheme"},"cadence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cadence"},"amount":{"type":"number","title":"Amount"},"monthly_amount":{"type":"number","title":"Monthly Amount"},"occurrences":{"type":"integer","title":"Occurrences"},"last_seen":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Seen"},"next_expected":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Expected"},"confidence":{"type":"number","title":"Confidence"},"evidence":{"type":"string","title":"Evidence"},"price_changes":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Price Changes","default":[]},"correction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Correction"}},"type":"object","required":["stream_key","display","state","kind","amount","monthly_amount","occurrences","confidence","evidence"],"title":"ReviewStream"},"ReviewTrait":{"properties":{"state":{"type":"string","title":"State"},"trait":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trait"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence"},"evidence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Evidence"},"days_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days Remaining"},"pay_cycles_observed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pay Cycles Observed"},"overdraft_warning_allowed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Overdraft Warning Allowed"}},"type":"object","required":["state"],"title":"ReviewTrait"},"RewardItem":{"properties":{"id":{"type":"string","title":"Id"},"reward_type":{"type":"string","title":"Reward Type"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","title":"Created At"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["id","reward_type","status","created_at"],"title":"RewardItem"},"RiskLevel-Input":{"type":"string","enum":["cautious","balanced","adventurous"],"title":"RiskLevel"},"RiskLevel-Output":{"properties":{"level":{"type":"string","title":"Level"},"message":{"type":"string","title":"Message"},"min_projected_balance":{"type":"number","title":"Min Projected Balance"},"min_balance_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Min Balance Date"}},"type":"object","required":["level","message","min_projected_balance","min_balance_date"],"title":"RiskLevel"},"RiskProfileBody":{"properties":{"profile":{"type":"string","title":"Profile"},"score":{"type":"integer","title":"Score"}},"type":"object","required":["profile","score"],"title":"RiskProfileBody"},"RuleDescription":{"properties":{"rule":{"type":"string","title":"Rule"},"name":{"type":"string","title":"Name"},"threshold":{"type":"string","title":"Threshold"},"rationale":{"type":"string","title":"Rationale"},"scope_required":{"type":"string","title":"Scope Required"}},"type":"object","required":["rule","name","threshold","rationale","scope_required"],"title":"RuleDescription"},"RuleNotRun":{"properties":{"rule":{"type":"string","title":"Rule"},"reason":{"type":"string","title":"Reason"}},"type":"object","required":["rule","reason"],"title":"RuleNotRun","description":"A rule that could not run, and why. An empty alert list means\n\"nothing material happened\"; this is how an adviser tells that apart\nfrom \"the rule never ran because the client did not share income\"."},"SalaryCheckResponse":{"properties":{"salary_detected":{"type":"boolean","title":"Salary Detected"},"amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Amount"},"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date"},"account_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Name"},"already_allocated":{"type":"boolean","title":"Already Allocated","default":false}},"type":"object","required":["salary_detected"],"title":"SalaryCheckResponse"},"SalarySacrificeResponse":{"properties":{"total_potential_saving":{"type":"number","title":"Total Potential Saving"},"schemes":{"items":{"$ref":"#/components/schemas/SalarySacrificeScheme"},"type":"array","title":"Schemes"}},"type":"object","required":["total_potential_saving","schemes"],"title":"SalarySacrificeResponse"},"SalarySacrificeScheme":{"properties":{"name":{"type":"string","title":"Name"},"annual_saving":{"type":"number","title":"Annual Saving"},"monthly_saving":{"type":"number","title":"Monthly Saving"},"eligible":{"type":"boolean","title":"Eligible"},"eligibility_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Eligibility Reason"},"how_to_claim":{"type":"string","title":"How To Claim"},"hmrc_url":{"type":"string","title":"Hmrc Url"}},"type":"object","required":["name","annual_saving","monthly_saving","eligible","eligibility_reason","how_to_claim","hmrc_url"],"title":"SalarySacrificeScheme"},"SaveRulesRequest":{"properties":{"rules":{"items":{"$ref":"#/components/schemas/PaydayRule"},"type":"array","title":"Rules"}},"type":"object","required":["rules"],"title":"SaveRulesRequest"},"SaveRulesResponse":{"properties":{"rules":{"items":{"$ref":"#/components/schemas/PaydayRule"},"type":"array","title":"Rules"},"total_allocated":{"type":"number","title":"Total Allocated"},"remaining_after_rules":{"type":"number","title":"Remaining After Rules"},"timeline":{"items":{"$ref":"#/components/schemas/TimelineEvent"},"type":"array","title":"Timeline"}},"type":"object","required":["rules","total_allocated","remaining_after_rules","timeline"],"title":"SaveRulesResponse"},"SavingsResponse":{"properties":{"total_annual_saving":{"type":"number","title":"Total Annual Saving"},"cumulative_saving_to_date":{"type":"number","title":"Cumulative Saving To Date"},"switch_count":{"type":"integer","title":"Switch Count"},"per_category":{"items":{"$ref":"#/components/schemas/PerCategorySaving"},"type":"array","title":"Per Category"},"first_switch_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Switch Date"}},"type":"object","required":["total_annual_saving","cumulative_saving_to_date","switch_count","per_category"],"title":"SavingsResponse"},"ScanResponse":{"properties":{"scan_date":{"type":"string","title":"Scan Date"},"created":{"items":{"type":"string"},"type":"array","title":"Created"},"failed":{"items":{"type":"string"},"type":"array","title":"Failed"},"total_pending":{"type":"integer","title":"Total Pending"},"free_apis_succeeded":{"items":{"type":"string"},"type":"array","title":"Free Apis Succeeded"},"free_apis_failed":{"items":{"type":"string"},"type":"array","title":"Free Apis Failed"},"ofgem_monthly_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ofgem Monthly Cost"}},"type":"object","required":["scan_date","created","failed","total_pending","free_apis_succeeded","free_apis_failed","ofgem_monthly_cost"],"title":"ScanResponse"},"ScenarioInput":{"properties":{"type":{"type":"string","title":"Type"},"change_amount":{"type":"number","title":"Change Amount"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},"type":"object","required":["type","change_amount"],"title":"ScenarioInput"},"ScenarioResult":{"properties":{"type":{"type":"string","title":"Type"},"description":{"type":"string","title":"Description"},"monthly_impact":{"type":"number","title":"Monthly Impact"},"annual_impact":{"type":"number","title":"Annual Impact"},"five_year_impact":{"type":"number","title":"Five Year Impact"},"projected_savings_balance":{"type":"number","title":"Projected Savings Balance"},"comparison":{"additionalProperties":true,"type":"object","title":"Comparison"}},"type":"object","required":["type","description","monthly_impact","annual_impact","five_year_impact","projected_savings_balance","comparison"],"title":"ScenarioResult"},"ScopeCatalogue":{"properties":{"scopes":{"items":{"$ref":"#/components/schemas/ScopeInfo"},"type":"array","title":"Scopes"},"default_scopes":{"items":{"type":"string"},"type":"array","title":"Default Scopes"}},"type":"object","required":["scopes","default_scopes"],"title":"ScopeCatalogue"},"ScopeInfo":{"properties":{"scope":{"type":"string","title":"Scope"},"label":{"type":"string","title":"Label"},"covers":{"type":"string","title":"Covers"}},"type":"object","required":["scope","label","covers"],"title":"ScopeInfo"},"ScopeUpdate":{"properties":{"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"}},"type":"object","required":["scopes"],"title":"ScopeUpdate"},"ScopeUpdateRequest":{"properties":{"balances_and_assets":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Balances And Assets"},"income_and_payday":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Income And Payday"}},"type":"object","title":"ScopeUpdateRequest"},"ScopeUpdateResponse":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"covers":{"items":{"type":"string"},"type":"array","title":"Covers"}},"type":"object","required":["id","status","scopes","covers"],"title":"ScopeUpdateResponse"},"SeedRequest":{"properties":{"user_id":{"type":"string","title":"User Id"}},"type":"object","required":["user_id"],"title":"SeedRequest"},"SendMessageRequest":{"properties":{"content":{"type":"string","maxLength":5000,"minLength":1,"title":"Content"}},"type":"object","required":["content"],"title":"SendMessageRequest"},"SmartRecommendation":{"properties":{"id":{"type":"string","title":"Id"},"category":{"type":"string","title":"Category"},"priority":{"type":"integer","title":"Priority"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"saving_amount":{"type":"number","title":"Saving Amount"},"recommended_product_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recommended Product Id"},"ai_reasoning":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Reasoning"}},"type":"object","required":["id","category","priority","title","description","saving_amount"],"title":"SmartRecommendation"},"SmartRecommendationsResponse":{"properties":{"recommendations":{"items":{"$ref":"#/components/schemas/SmartRecommendation"},"type":"array","title":"Recommendations"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["recommendations","total"],"title":"SmartRecommendationsResponse"},"SmartSuggestion":{"properties":{"type":{"type":"string","title":"Type"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"amount":{"type":"number","title":"Amount"},"timing":{"type":"string","title":"Timing"},"timing_label":{"type":"string","title":"Timing Label"},"icon":{"type":"string","title":"Icon"},"color_key":{"type":"string","title":"Color Key"}},"type":"object","required":["type","title","description","amount","timing","timing_label","icon","color_key"],"title":"SmartSuggestion"},"SnapshotResponse":{"properties":{"id":{"type":"string","title":"Id"},"total_assets":{"type":"number","title":"Total Assets"},"total_debts":{"type":"number","title":"Total Debts"},"net_worth":{"type":"number","title":"Net Worth"},"breakdown":{"additionalProperties":true,"type":"object","title":"Breakdown"},"snapshot_date":{"type":"string","title":"Snapshot Date"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","total_assets","total_debts","net_worth","breakdown","snapshot_date","created_at"],"title":"SnapshotResponse"},"SourceNoteOut":{"properties":{"source":{"type":"string","title":"Source"},"label":{"type":"string","title":"Label"},"as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"As Of"},"is_estimate":{"type":"boolean","title":"Is Estimate"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["source","label","as_of","is_estimate"],"title":"SourceNoteOut"},"SpendingAggregateResponse":{"properties":{"from":{"type":"string","format":"date","title":"From"},"to":{"type":"string","format":"date","title":"To"},"group_by":{"items":{"type":"string"},"type":"array","title":"Group By"},"currency":{"type":"string","title":"Currency"},"total":{"type":"number","title":"Total"},"count":{"type":"integer","title":"Count"},"by_category":{"anyOf":[{"items":{"$ref":"#/components/schemas/SpendingCategoryTotal"},"type":"array"},{"type":"null"}],"title":"By Category"},"by_month":{"anyOf":[{"items":{"$ref":"#/components/schemas/SpendingMonthTotal"},"type":"array"},{"type":"null"}],"title":"By Month"},"cells":{"anyOf":[{"items":{"$ref":"#/components/schemas/SpendingCell"},"type":"array"},{"type":"null"}],"title":"Cells"}},"type":"object","required":["from","to","group_by","currency","total","count"],"title":"SpendingAggregateResponse"},"SpendingCategoryTotal":{"properties":{"category":{"type":"string","title":"Category"},"total":{"type":"number","title":"Total"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["category","total","count"],"title":"SpendingCategoryTotal"},"SpendingCell":{"properties":{"category":{"type":"string","title":"Category"},"month":{"type":"string","title":"Month"},"total":{"type":"number","title":"Total"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["category","month","total","count"],"title":"SpendingCell"},"SpendingExportRequest":{"properties":{"period":{"type":"string","title":"Period"},"format":{"type":"string","title":"Format","default":"csv"},"merchant":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Merchant"}},"type":"object","required":["period"],"title":"SpendingExportRequest"},"SpendingMonthTotal":{"properties":{"month":{"type":"string","title":"Month"},"total":{"type":"number","title":"Total"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["month","total","count"],"title":"SpendingMonthTotal"},"SplitBillCreate":{"properties":{"description":{"type":"string","maxLength":255,"title":"Description"},"total_amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Total Amount"},"split_type":{"type":"string","title":"Split Type","default":"50-50"},"user1_share":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"User1 Share"},"user2_share":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"User2 Share"},"i_paid":{"type":"boolean","title":"I Paid","default":true},"transaction_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Transaction Id"}},"type":"object","required":["description","total_amount"],"title":"SplitBillCreate"},"SplitBillResponse":{"properties":{"id":{"type":"string","title":"Id"},"description":{"type":"string","title":"Description"},"total_amount":{"type":"number","title":"Total Amount"},"split_type":{"type":"string","title":"Split Type"},"user1_share":{"type":"number","title":"User1 Share"},"user2_share":{"type":"number","title":"User2 Share"},"settled":{"type":"boolean","title":"Settled"},"created_at":{"type":"string","title":"Created At"},"settled_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Settled At"},"you_paid":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"You Paid"},"your_share":{"type":"number","title":"Your Share"},"their_share":{"type":"number","title":"Their Share"},"transaction_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transaction Id"}},"type":"object","required":["id","description","total_amount","split_type","user1_share","user2_share","settled","created_at","settled_at","you_paid","your_share","their_share","transaction_id"],"title":"SplitBillResponse"},"SplitBody":{"properties":{"client_id":{"type":"string","format":"uuid","title":"Client Id"},"base_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Base Updated At"},"bills":{"type":"string","title":"Bills"},"spending":{"type":"string","title":"Spending"},"targets":{"items":{"$ref":"#/components/schemas/SplitTarget"},"type":"array","title":"Targets","default":[]}},"type":"object","required":["client_id","bills","spending"],"title":"SplitBody"},"SplitItem":{"properties":{"category":{"type":"string","title":"Category"},"amount":{"type":"number","exclusiveMinimum":0.0,"title":"Amount"}},"type":"object","required":["category","amount"],"title":"SplitItem"},"SplitTarget":{"properties":{"type":{"type":"string","enum":["goal","pot","investment"],"title":"Type"},"id":{"type":"string","maxLength":64,"minLength":1,"title":"Id"},"amount":{"type":"string","title":"Amount"}},"type":"object","required":["type","id","amount"],"title":"SplitTarget"},"StatusAccount":{"properties":{"institution":{"type":"string","title":"Institution"},"institution_logo":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Institution Logo"},"account_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Name"},"account_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Type"},"id":{"type":"string","title":"Id"}},"type":"object","required":["institution","id"],"title":"StatusAccount"},"StatusResponse":{"properties":{"status":{"type":"string","title":"Status"},"accounts":{"items":{"$ref":"#/components/schemas/StatusAccount"},"type":"array","title":"Accounts","default":[]},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["status"],"title":"StatusResponse"},"StoryResponse":{"properties":{"story":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Story"},"generated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Generated At"}},"type":"object","required":["story"],"title":"StoryResponse"},"StreakCheckResponse":{"properties":{"current_streak":{"type":"integer","title":"Current Streak"},"longest_streak":{"type":"integer","title":"Longest Streak"},"total_streak_days":{"type":"integer","title":"Total Streak Days"},"streak_start_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Streak Start Date"},"last_checked_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Checked Date"},"next_milestone":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Milestone"},"next_milestone_xp":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Milestone Xp"},"days_to_milestone":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days To Milestone"},"xp_awarded":{"items":{"$ref":"#/components/schemas/XPAward"},"type":"array","title":"Xp Awarded"}},"type":"object","required":["current_streak","longest_streak","total_streak_days","streak_start_date","last_checked_date","next_milestone","next_milestone_xp","days_to_milestone","xp_awarded"],"title":"StreakCheckResponse"},"StreakStatusResponse":{"properties":{"current_streak":{"type":"integer","title":"Current Streak"},"longest_streak":{"type":"integer","title":"Longest Streak"},"total_streak_days":{"type":"integer","title":"Total Streak Days"},"streak_start_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Streak Start Date"},"daily_budget":{"type":"number","title":"Daily Budget"},"today_spending":{"type":"number","title":"Today Spending"},"budget_remaining":{"type":"number","title":"Budget Remaining"},"on_track_today":{"type":"boolean","title":"On Track Today"},"next_milestone":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Milestone"},"next_milestone_xp":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Milestone Xp"},"days_to_milestone":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days To Milestone"},"earned_milestones":{"items":{"type":"integer"},"type":"array","title":"Earned Milestones"},"milestones":{"additionalProperties":{"type":"integer"},"type":"object","title":"Milestones"}},"type":"object","required":["current_streak","longest_streak","total_streak_days","streak_start_date","daily_budget","today_spending","budget_remaining","on_track_today","next_milestone","next_milestone_xp","days_to_milestone","earned_milestones","milestones"],"title":"StreakStatusResponse"},"StudentLoanResponse":{"properties":{"plan_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Type"},"monthly_repayment":{"type":"number","title":"Monthly Repayment"},"annual_repayment":{"type":"number","title":"Annual Repayment"},"threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Threshold"},"repayment_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Repayment Rate"},"estimated_years_remaining":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Estimated Years Remaining"},"detected_from_transactions":{"type":"boolean","title":"Detected From Transactions"}},"type":"object","required":["plan_type","monthly_repayment","annual_repayment","threshold","repayment_rate","estimated_years_remaining","detected_from_transactions"],"title":"StudentLoanResponse"},"SubscriptionAuditResponse":{},"SubscriptionItem":{"properties":{"name":{"type":"string","title":"Name"},"amount":{"type":"number","title":"Amount"},"annual_cost":{"type":"number","title":"Annual Cost"},"category":{"type":"string","title":"Category"},"category_label":{"type":"string","title":"Category Label"},"status":{"type":"string","title":"Status"},"usage":{"type":"string","title":"Usage"},"price_change":{"anyOf":[{"$ref":"#/components/schemas/PriceChange"},{"type":"null"}]},"cancel_saving_annual":{"type":"number","title":"Cancel Saving Annual"},"months_active":{"type":"integer","title":"Months Active"},"confidence":{"type":"string","title":"Confidence","default":"medium"},"confidence_score":{"type":"number","title":"Confidence Score","default":75.0},"display_status":{"type":"string","title":"Display Status","default":"confirmed"},"user_confirmed":{"type":"boolean","title":"User Confirmed","default":false},"interval_type":{"type":"string","title":"Interval Type","default":"monthly"},"amount_variance_pct":{"type":"number","title":"Amount Variance Pct","default":0.0},"cancellation_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cancellation Url"},"staleness":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Staleness"},"last_seen":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Seen"},"overpaying":{"anyOf":[{"$ref":"#/components/schemas/OverpayingInfo"},{"type":"null"}]},"annual_saving_opportunity":{"anyOf":[{"$ref":"#/components/schemas/AnnualSavingInfo"},{"type":"null"}]},"merchant_matched":{"type":"boolean","title":"Merchant Matched","default":false},"bill_split_pct":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bill Split Pct"}},"type":"object","required":["name","amount","annual_cost","category","category_label","status","usage","price_change","cancel_saving_annual","months_active"],"title":"SubscriptionItem"},"SubscriptionPreferenceResponse":{"properties":{"id":{"type":"string","title":"Id"},"merchant_name":{"type":"string","title":"Merchant Name"},"status":{"type":"string","title":"Status"},"amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Amount"},"frequency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Frequency"},"billing_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Type"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","merchant_name","status","amount","frequency","created_at"],"title":"SubscriptionPreferenceResponse"},"SubscriptionSummaryItem":{"properties":{"merchant":{"type":"string","title":"Merchant"},"category":{"type":"string","title":"Category"},"monthly_cost":{"type":"number","title":"Monthly Cost"},"split_pct":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Split Pct"},"full_monthly_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Full Monthly Cost"},"interval_type":{"type":"string","title":"Interval Type"},"months_active":{"type":"integer","title":"Months Active"},"last_charge_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Charge Date"},"annual_saving":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Annual Saving"},"annual_plan_cost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Annual Plan Cost"},"charge_count":{"type":"integer","title":"Charge Count","default":0},"user_overridden":{"type":"boolean","title":"User Overridden","default":false},"confirmation_status":{"type":"string","title":"Confirmation Status","default":"confirmed"}},"type":"object","required":["merchant","category","monthly_cost","interval_type","months_active"],"title":"SubscriptionSummaryItem"},"SuggestedAllocationRequest":{"properties":{"goals":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Goals"}},"type":"object","title":"SuggestedAllocationRequest"},"SuggestionAllocation":{"properties":{"category":{"type":"string","title":"Category"},"amount":{"type":"number","exclusiveMinimum":0.0,"title":"Amount"},"percentage":{"type":"number","title":"Percentage"}},"type":"object","required":["category","amount","percentage"],"title":"SuggestionAllocation"},"SupportHistoryResponse":{"properties":{"session_id":{"type":"string","title":"Session Id"},"messages":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Messages"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["session_id","messages","created_at"],"title":"SupportHistoryResponse"},"SupportMessageRequest":{"properties":{"content":{"type":"string","maxLength":2000,"minLength":1,"title":"Content"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"}},"type":"object","required":["content"],"title":"SupportMessageRequest"},"SupportMessageResponse":{"properties":{"session_id":{"type":"string","title":"Session Id"},"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["session_id","role","content","created_at"],"title":"SupportMessageResponse"},"SyncCronResponse":{"properties":{"status":{"type":"string","title":"Status"},"users_synced":{"type":"integer","title":"Users Synced"},"total_transactions":{"type":"integer","title":"Total Transactions"}},"type":"object","required":["status","users_synced","total_transactions"],"title":"SyncCronResponse"},"TaxBreakdown":{"properties":{"gross":{"type":"number","title":"Gross"},"tax":{"type":"number","title":"Tax"},"ni":{"type":"number","title":"Ni"},"net":{"type":"number","title":"Net"},"monthly_net":{"type":"number","title":"Monthly Net"},"tax_band":{"type":"string","title":"Tax Band"}},"type":"object","required":["gross","tax","ni","net","monthly_net","tax_band"],"title":"TaxBreakdown"},"TaxDeadline":{"properties":{"name":{"type":"string","title":"Name"},"date":{"type":"string","title":"Date"},"days_remaining":{"type":"integer","title":"Days Remaining"},"category":{"type":"string","title":"Category"},"description":{"type":"string","title":"Description"}},"type":"object","required":["name","date","days_remaining","category","description"],"title":"TaxDeadline"},"TaxDeadlinesResponse":{"properties":{"deadlines":{"items":{"$ref":"#/components/schemas/TaxDeadline"},"type":"array","title":"Deadlines"}},"type":"object","required":["deadlines"],"title":"TaxDeadlinesResponse"},"TaxExportRequest":{"properties":{"tax_year":{"type":"string","title":"Tax Year","default":"2025_2026"}},"type":"object","title":"TaxExportRequest"},"TaxProfileRequest":{"properties":{"annual_salary":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Annual Salary"},"tax_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tax Code"},"student_loan_plan":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Student Loan Plan"},"has_children":{"type":"boolean","title":"Has Children","default":false},"num_children":{"type":"integer","title":"Num Children","default":0},"employer_pension_match":{"type":"boolean","title":"Employer Pension Match","default":false},"employer_match_percentage":{"type":"number","title":"Employer Match Percentage","default":0},"pension_contribution_pct":{"type":"number","title":"Pension Contribution Pct","default":0},"self_employed":{"type":"boolean","title":"Self Employed","default":false}},"type":"object","title":"TaxProfileRequest"},"TaxProfileResponse":{"properties":{"annual_salary":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Annual Salary"},"tax_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tax Code"},"student_loan_plan":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Student Loan Plan"},"has_children":{"type":"boolean","title":"Has Children"},"num_children":{"type":"integer","title":"Num Children"},"employer_pension_match":{"type":"boolean","title":"Employer Pension Match"},"employer_match_percentage":{"type":"number","title":"Employer Match Percentage"},"pension_contribution_pct":{"type":"number","title":"Pension Contribution Pct"},"self_employed":{"type":"boolean","title":"Self Employed"},"has_profile":{"type":"boolean","title":"Has Profile"},"is_pre_filled":{"type":"boolean","title":"Is Pre Filled","default":false},"pre_fill_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pre Fill Source"}},"type":"object","required":["annual_salary","tax_code","student_loan_plan","has_children","num_children","employer_pension_match","employer_match_percentage","pension_contribution_pct","self_employed","has_profile"],"title":"TaxProfileResponse"},"TaxSummaryResponse":{"properties":{"annual_income":{"type":"number","title":"Annual Income"},"tax_band":{"type":"string","title":"Tax Band"},"income_tax":{"type":"number","title":"Income Tax"},"national_insurance":{"type":"number","title":"National Insurance"},"effective_rate":{"type":"number","title":"Effective Rate"},"take_home":{"type":"number","title":"Take Home"},"monthly_take_home":{"type":"number","title":"Monthly Take Home"},"personal_allowance":{"type":"number","title":"Personal Allowance"},"distance_to_next_band":{"type":"number","title":"Distance To Next Band"},"next_band":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Band"},"basic_taxable":{"type":"number","title":"Basic Taxable"},"higher_taxable":{"type":"number","title":"Higher Taxable"},"additional_taxable":{"type":"number","title":"Additional Taxable"},"basic_tax":{"type":"number","title":"Basic Tax"},"higher_tax":{"type":"number","title":"Higher Tax"},"additional_tax":{"type":"number","title":"Additional Tax"},"tax_year":{"type":"string","title":"Tax Year"},"days_remaining":{"type":"integer","title":"Days Remaining"},"near_threshold":{"type":"boolean","title":"Near Threshold"},"threshold_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Threshold Message"}},"type":"object","required":["annual_income","tax_band","income_tax","national_insurance","effective_rate","take_home","monthly_take_home","personal_allowance","distance_to_next_band","next_band","basic_taxable","higher_taxable","additional_taxable","basic_tax","higher_tax","additional_tax","tax_year","days_remaining","near_threshold","threshold_message"],"title":"TaxSummaryResponse"},"TaxTip":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"explanation":{"type":"string","title":"Explanation"},"potential_saving":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Potential Saving"},"action":{"type":"string","title":"Action"},"category":{"type":"string","title":"Category"},"priority":{"type":"integer","title":"Priority"}},"type":"object","required":["id","title","explanation","potential_saving","action","category","priority"],"title":"TaxTip"},"TaxTipItem":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"explanation":{"type":"string","title":"Explanation"},"potential_saving":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Potential Saving"},"action":{"type":"string","title":"Action"},"category":{"type":"string","title":"Category"},"priority":{"type":"integer","title":"Priority"},"section_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Section Ref"}},"type":"object","required":["id","title","explanation","potential_saving","action","category","priority"],"title":"TaxTipItem"},"TaxTipsAIResponse":{"properties":{"tips":{"items":{"$ref":"#/components/schemas/TaxTipItem"},"type":"array","title":"Tips"},"generated_at":{"type":"string","title":"Generated At"}},"type":"object","required":["tips","generated_at"],"title":"TaxTipsAIResponse"},"TaxTipsResponse":{"properties":{"tips":{"items":{"$ref":"#/components/schemas/TaxTip"},"type":"array","title":"Tips"}},"type":"object","required":["tips"],"title":"TaxTipsResponse"},"TestNotificationRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"}},"type":"object","title":"TestNotificationRequest"},"TestNotificationResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","message"],"title":"TestNotificationResponse"},"TickBody":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"cycle_id":{"type":"string","format":"uuid","title":"Cycle Id"},"suggestion_id":{"type":"string","maxLength":80,"minLength":3,"title":"Suggestion Id"},"action":{"type":"string","enum":["tick","untick"],"title":"Action"},"amount":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Amount"},"reverses":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Reverses"}},"type":"object","required":["id","cycle_id","suggestion_id","action"],"title":"TickBody"},"TimelineEvent":{"properties":{"order":{"type":"integer","title":"Order"},"day":{"type":"integer","title":"Day"},"label":{"type":"string","title":"Label"},"amount":{"type":"number","title":"Amount"},"type":{"type":"string","title":"Type"},"icon":{"type":"string","title":"Icon"},"color_key":{"type":"string","title":"Color Key"}},"type":"object","required":["order","day","label","amount","type","icon","color_key"],"title":"TimelineEvent"},"TokenCreate":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"},"scopes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Scopes"}},"type":"object","required":["name"],"title":"TokenCreate"},"TokenCreated":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"token":{"type":"string","title":"Token"},"created_at":{"type":"string","title":"Created At"},"expires_at":{"type":"string","title":"Expires At"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"covers":{"items":{"type":"string"},"type":"array","title":"Covers"}},"type":"object","required":["id","name","token","created_at","expires_at","scopes","covers"],"title":"TokenCreated"},"TokenItem":{"properties":{"id":{"type":"string","title":"Id"},"kind":{"type":"string","title":"Kind"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"},"created_at":{"type":"string","title":"Created At"},"connected_at":{"type":"string","title":"Connected At"},"last_used_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Used At"},"revoked":{"type":"boolean","title":"Revoked"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"covers":{"items":{"type":"string"},"type":"array","title":"Covers"},"legacy_full_access":{"type":"boolean","title":"Legacy Full Access"}},"type":"object","required":["id","kind","name","client_id","created_at","connected_at","last_used_at","revoked","expires_at","scopes","covers","legacy_full_access"],"title":"TokenItem"},"TokenListResponse":{"properties":{"tokens":{"items":{"$ref":"#/components/schemas/TokenItem"},"type":"array","title":"Tokens"}},"type":"object","required":["tokens"],"title":"TokenListResponse"},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"type":"string","title":"Refresh Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"is_new_user":{"type":"boolean","title":"Is New User","default":false}},"type":"object","required":["access_token","refresh_token"],"title":"TokenResponse"},"TrackClickRequest":{"properties":{"product_id":{"type":"string","maxLength":100,"title":"Product Id"},"source":{"type":"string","maxLength":100,"title":"Source","default":"marketplace"}},"type":"object","required":["product_id"],"title":"TrackClickRequest"},"TrackClickResponse":{"properties":{"click_id":{"type":"string","title":"Click Id"},"tracked":{"type":"boolean","title":"Tracked"}},"type":"object","required":["click_id","tracked"],"title":"TrackClickResponse"},"TrainingStats":{"properties":{"total_transaction_records":{"type":"integer","title":"Total Transaction Records"},"total_conversation_records":{"type":"integer","title":"Total Conversation Records"},"verified_pct":{"type":"number","title":"Verified Pct"},"avg_quality_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Quality Score"},"records_last_7_days":{"type":"integer","title":"Records Last 7 Days"}},"type":"object","required":["total_transaction_records","total_conversation_records","verified_pct","avg_quality_score","records_last_7_days"],"title":"TrainingStats"},"TransactionBreakdown":{"properties":{"date":{"type":"string","title":"Date"},"description":{"type":"string","title":"Description"},"amount":{"type":"number","title":"Amount"},"merchant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Merchant Name"}},"type":"object","required":["date","description","amount"],"title":"TransactionBreakdown"},"TransactionItem":{"properties":{"id":{"type":"string","title":"Id"},"date":{"type":"string","format":"date","title":"Date"},"description":{"type":"string","title":"Description"},"merchant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Merchant Name"},"amount":{"type":"number","title":"Amount"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"pot":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pot"},"is_recurring":{"type":"boolean","title":"Is Recurring"}},"type":"object","required":["id","date","description","merchant_name","amount","category","pot","is_recurring"],"title":"TransactionItem"},"TransactionListResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TransactionResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"pages":{"type":"integer","title":"Pages"}},"type":"object","required":["items","total","page","pages"],"title":"TransactionListResponse"},"TransactionPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TransactionItem"},"type":"array","title":"Items"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total":{"type":"integer","title":"Total"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["items","page","page_size","total","total_pages"],"title":"TransactionPage"},"TransactionResponse":{"properties":{"id":{"type":"string","title":"Id"},"account_id":{"type":"string","title":"Account Id"},"external_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Id"},"date":{"type":"string","title":"Date"},"description":{"type":"string","title":"Description"},"amount":{"type":"number","title":"Amount"},"currency":{"type":"string","title":"Currency"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"merchant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Merchant Name"},"is_recurring":{"type":"boolean","title":"Is Recurring"},"recurring_group":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurring Group"},"is_internal_transfer":{"type":"boolean","title":"Is Internal Transfer","default":false},"transaction_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transaction Type"},"recurring_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurring Category"},"bill_split_pct":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bill Split Pct"},"effective_amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Effective Amount"},"is_investment_contribution":{"type":"boolean","title":"Is Investment Contribution","default":false}},"type":"object","required":["id","account_id","external_id","date","description","amount","currency","category","merchant_name","is_recurring","recurring_group"],"title":"TransactionResponse"},"TriggerRequest":{"properties":{"user_id":{"type":"string","title":"User Id"},"event":{"type":"string","title":"Event"},"params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Params"}},"type":"object","required":["user_id","event"],"title":"TriggerRequest"},"UnreadCountResponse":{"properties":{"unread_count":{"type":"integer","title":"Unread Count"}},"type":"object","required":["unread_count"],"title":"UnreadCountResponse"},"UnsubscribeRequest":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"UnsubscribeRequest"},"UnsubscribeResponse":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"UnsubscribeResponse"},"UpcomingBill":{"properties":{"merchant":{"type":"string","title":"Merchant"},"amount":{"type":"number","title":"Amount"},"expected_date":{"type":"string","title":"Expected Date"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"days_away":{"type":"integer","title":"Days Away"}},"type":"object","required":["merchant","amount","expected_date","category","days_away"],"title":"UpcomingBill"},"UpcomingRenewal":{"properties":{"name":{"type":"string","title":"Name"},"next_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Date"},"amount":{"type":"number","title":"Amount"},"category":{"type":"string","title":"Category"}},"type":"object","required":["name","next_date","amount","category"],"title":"UpcomingRenewal"},"UpdateCategoryRequest":{"properties":{"category":{"type":"string","title":"Category"},"scope":{"type":"string","enum":["merchant","merchant_all","transaction"],"title":"Scope","default":"merchant"}},"type":"object","required":["category"],"title":"UpdateCategoryRequest"},"UpdateCategoryResponse":{"properties":{"transaction_id":{"type":"string","title":"Transaction Id"},"old_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Old Category"},"new_category":{"type":"string","title":"New Category"},"merchant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Merchant Name"},"override_created":{"type":"boolean","title":"Override Created"},"retro_updated":{"type":"integer","title":"Retro Updated","default":0}},"type":"object","required":["transaction_id","old_category","new_category","merchant_name","override_created"],"title":"UpdateCategoryResponse"},"UpdateProfessionRequest":{"properties":{"profession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profession"},"employer_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Employer Name"}},"type":"object","title":"UpdateProfessionRequest"},"UpdateTargetRequest":{"properties":{"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"sort_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort Code"},"account_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Number"},"holder_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Holder Name"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"UpdateTargetRequest"},"UpdateUserRequest":{"properties":{"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"monthly_income":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Monthly Income"}},"type":"object","title":"UpdateUserRequest"},"UsageResponse":{"properties":{"messages_used_today":{"type":"integer","title":"Messages Used Today"},"messages_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Messages Remaining"},"is_premium":{"type":"boolean","title":"Is Premium"},"daily_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Daily Limit"},"subscription_tier":{"type":"string","title":"Subscription Tier","default":"free"},"monthly_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Monthly Limit"},"messages_used_this_month":{"type":"integer","title":"Messages Used This Month","default":0},"tokens_used":{"type":"integer","title":"Tokens Used","default":0},"token_budget":{"type":"integer","title":"Token Budget","default":50000},"tokens_remaining":{"type":"integer","title":"Tokens Remaining","default":50000}},"type":"object","required":["messages_used_today","messages_remaining","is_premium","daily_limit"],"title":"UsageResponse"},"UserResponse":{"properties":{"id":{"type":"string","title":"Id"},"email":{"type":"string","title":"Email"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"monthly_income":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Monthly Income"},"created_at":{"type":"string","title":"Created At"},"email_verified":{"type":"boolean","title":"Email Verified","default":false},"is_premium":{"type":"boolean","title":"Is Premium","default":false},"subscription_tier":{"type":"string","title":"Subscription Tier","default":"free"},"profession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profession"},"employer_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Employer Name"},"profession_detected_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profession Detected At"},"ai_disclosure_acknowledged_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Disclosure Acknowledged At"},"acquisition_recorded_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acquisition Recorded At"},"subscription_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Source"},"features":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Features","default":{}}},"type":"object","required":["id","email","full_name","monthly_income","created_at"],"title":"UserResponse"},"ValidateRequest":{"properties":{"code":{"type":"string","title":"Code"}},"type":"object","required":["code"],"title":"ValidateRequest"},"ValidateResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"referrer_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Name"}},"type":"object","required":["valid"],"title":"ValidateResponse"},"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"},"ValuationBody":{"properties":{"value":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Value"},"date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date"}},"type":"object","required":["value"],"title":"ValuationBody"},"VerifyEmailRequest":{"properties":{"code":{"type":"string","title":"Code"}},"type":"object","required":["code"],"title":"VerifyEmailRequest"},"VerifyTransferItem":{"properties":{"rule_id":{"type":"string","title":"Rule Id"},"amount":{"type":"number","exclusiveMinimum":0.0,"title":"Amount"}},"type":"object","required":["rule_id","amount"],"title":"VerifyTransferItem"},"VerifyTransferResult":{"properties":{"rule_id":{"type":"string","title":"Rule Id"},"matched":{"type":"boolean","title":"Matched"},"matched_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Matched Date"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["rule_id","matched"],"title":"VerifyTransferResult"},"VerifyTransfersRequest":{"properties":{"since":{"type":"string","format":"date","title":"Since"},"items":{"items":{"$ref":"#/components/schemas/VerifyTransferItem"},"type":"array","title":"Items"}},"type":"object","required":["since","items"],"title":"VerifyTransfersRequest"},"VerifyTransfersResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/VerifyTransferResult"},"type":"array","title":"Results"}},"type":"object","required":["results"],"title":"VerifyTransfersResponse"},"VirtualPotRequest":{"properties":{"rules":{"items":{"$ref":"#/components/schemas/VirtualPotRule"},"type":"array","title":"Rules"}},"type":"object","required":["rules"],"title":"VirtualPotRequest"},"VirtualPotResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/VirtualPotResult"},"type":"array","title":"Results"}},"type":"object","required":["results"],"title":"VirtualPotResponse"},"VirtualPotResult":{"properties":{"rule_id":{"type":"string","title":"Rule Id"},"category":{"type":"string","title":"Category"},"amount":{"type":"number","title":"Amount"},"label":{"type":"string","title":"Label"},"status":{"type":"string","title":"Status"}},"type":"object","required":["rule_id","category","amount","label","status"],"title":"VirtualPotResult"},"VirtualPotRule":{"properties":{"rule_id":{"type":"string","title":"Rule Id"},"category":{"type":"string","title":"Category"},"amount":{"type":"number","exclusiveMinimum":0.0,"title":"Amount"},"label":{"type":"string","title":"Label"}},"type":"object","required":["rule_id","category","amount","label"],"title":"VirtualPotRule"},"WeeklyBriefingResponse":{"properties":{"sections":{"items":{"$ref":"#/components/schemas/BriefingSectionResponse"},"type":"array","title":"Sections"},"overall_score":{"type":"integer","title":"Overall Score"},"score_breakdown":{"additionalProperties":true,"type":"object","title":"Score Breakdown"},"generated_at":{"type":"string","title":"Generated At"}},"type":"object","required":["sections","overall_score","score_breakdown","generated_at"],"title":"WeeklyBriefingResponse"},"WhatIfRequest":{"properties":{"scenarios":{"items":{"$ref":"#/components/schemas/ScenarioInput"},"type":"array","minItems":1,"title":"Scenarios"}},"type":"object","required":["scenarios"],"title":"WhatIfRequest"},"WhatIfResponse":{"properties":{"scenarios":{"items":{"$ref":"#/components/schemas/ScenarioResult"},"type":"array","title":"Scenarios"},"combined_impact":{"$ref":"#/components/schemas/CombinedImpact"}},"type":"object","required":["scenarios","combined_impact"],"title":"WhatIfResponse"},"XPAward":{"properties":{"milestone":{"type":"integer","title":"Milestone"},"xp":{"type":"integer","title":"Xp"}},"type":"object","required":["milestone","xp"],"title":"XPAward"},"XPHistoryEntry":{"properties":{"action":{"type":"string","title":"Action"},"xp":{"type":"integer","title":"Xp"},"date":{"type":"string","title":"Date"},"description":{"type":"string","title":"Description"}},"type":"object","required":["action","xp","date","description"],"title":"XPHistoryEntry"},"XPResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"total_xp":{"type":"integer","title":"Total Xp"},"level":{"type":"integer","title":"Level"},"level_name":{"type":"string","title":"Level Name"},"xp_to_next_level":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Xp To Next Level"},"xp_current_level":{"type":"integer","title":"Xp Current Level"},"xp_next_level":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Xp Next Level"},"weekly_xp":{"type":"integer","title":"Weekly Xp"},"streak_weeks":{"type":"integer","title":"Streak Weeks"},"xp_history":{"items":{"$ref":"#/components/schemas/XPHistoryEntry"},"type":"array","title":"Xp History"}},"type":"object","required":["user_id","total_xp","level","level_name","xp_to_next_level","xp_current_level","xp_next_level","weekly_xp","streak_weeks","xp_history"],"title":"XPResponse"},"YearInNumbers":{"properties":{"total_transactions":{"type":"integer","title":"Total Transactions"},"unique_merchants":{"type":"integer","title":"Unique Merchants"},"most_active_day":{"type":"string","title":"Most Active Day"},"average_daily_spend":{"type":"number","title":"Average Daily Spend"},"subscriptions_total":{"type":"number","title":"Subscriptions Total"},"days_with_zero_spend":{"type":"integer","title":"Days With Zero Spend"}},"type":"object","required":["total_transactions","unique_merchants","most_active_day","average_daily_spend","subscriptions_total","days_with_zero_spend"],"title":"YearInNumbers"},"app__api__adviser__CategorySummary":{"properties":{"category":{"type":"string","title":"Category"},"total":{"type":"number","title":"Total"}},"type":"object","required":["category","total"],"title":"CategorySummary"},"app__api__adviser__InviteRequest":{"properties":{"client_label":{"type":"string","maxLength":255,"minLength":1,"title":"Client Label"},"client_email":{"type":"string","format":"email","title":"Client Email"},"scope":{"$ref":"#/components/schemas/ConsentScope","default":"category_totals"},"can_recategorise":{"type":"boolean","title":"Can Recategorise","default":false}},"type":"object","required":["client_label","client_email"],"title":"InviteRequest"},"app__api__adviser__InviteResponse":{"properties":{"grant_id":{"type":"string","title":"Grant Id"},"invite_token":{"type":"string","title":"Invite Token"},"invite_expires_at":{"type":"string","format":"date-time","title":"Invite Expires At"},"status":{"type":"string","title":"Status"}},"type":"object","required":["grant_id","invite_token","invite_expires_at","status"],"title":"InviteResponse"},"app__api__adviser__PotSummary":{"properties":{"pot":{"type":"string","title":"Pot"},"label":{"type":"string","title":"Label"},"total":{"type":"number","title":"Total"},"categories":{"items":{"$ref":"#/components/schemas/app__api__adviser__CategorySummary"},"type":"array","title":"Categories"}},"type":"object","required":["pot","label","total","categories"],"title":"PotSummary"},"app__api__banking__AccountResponse":{"properties":{"id":{"type":"string","title":"Id"},"connection_id":{"type":"string","title":"Connection Id"},"external_id":{"type":"string","title":"External Id"},"account_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Type"},"account_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Name"},"institution_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Institution Name"},"currency":{"type":"string","title":"Currency"},"balance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Balance"},"balance_updated":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Balance Updated"},"sort_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort Code"},"account_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Number"}},"type":"object","required":["id","connection_id","external_id","account_type","account_name","currency","balance","balance_updated","sort_code","account_number"],"title":"AccountResponse"},"app__api__banking__ConnectRequest":{"properties":{"institution_id":{"type":"string","title":"Institution Id"}},"type":"object","required":["institution_id"],"title":"ConnectRequest"},"app__api__banking__ConnectResponse":{"properties":{"authorisation_url":{"type":"string","title":"Authorisation Url"},"connection_id":{"type":"string","title":"Connection Id"}},"type":"object","required":["authorisation_url","connection_id"],"title":"ConnectResponse"},"app__api__banking__SeedResponse":{"properties":{"total_transactions":{"type":"integer","title":"Total Transactions"},"date_range":{"additionalProperties":true,"type":"object","title":"Date Range"},"categories":{"items":{"type":"string"},"type":"array","title":"Categories"},"total_spend":{"type":"number","title":"Total Spend"},"total_income":{"type":"number","title":"Total Income"},"account_id":{"type":"string","title":"Account Id"},"connection_id":{"type":"string","title":"Connection Id"},"recategorization":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Recategorization"}},"type":"object","required":["total_transactions","date_range","categories","total_spend","total_income","account_id","connection_id"],"title":"SeedResponse"},"app__api__banking__SyncResponse":{"properties":{"accounts_synced":{"type":"integer","title":"Accounts Synced"},"transactions_synced":{"type":"integer","title":"Transactions Synced"},"new_transactions":{"type":"integer","title":"New Transactions"}},"type":"object","required":["accounts_synced","transactions_synced","new_transactions"],"title":"SyncResponse"},"app__api__chat__SessionResponse":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"},"last_message_preview":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Message Preview"},"message_count":{"type":"integer","title":"Message Count","default":0}},"type":"object","required":["id","title","created_at","updated_at"],"title":"SessionResponse"},"app__api__codes__ClaimRequest":{"properties":{"code":{"type":"string","maxLength":80,"minLength":2,"title":"Code"}},"type":"object","required":["code"],"title":"ClaimRequest"},"app__api__codes__RedeemRequest":{"properties":{"code":{"type":"string","maxLength":80,"minLength":3,"title":"Code"}},"type":"object","required":["code"],"title":"RedeemRequest"},"app__api__consents__AcceptRequest":{"properties":{"invite_token":{"type":"string","title":"Invite Token"}},"type":"object","required":["invite_token"],"title":"AcceptRequest"},"app__api__goals__GoalCreate":{"properties":{"client_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Client Id"},"name":{"type":"string","title":"Name"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"target_amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Target Amount"},"saved_amount":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Saved Amount","default":"0"},"monthly_contribution":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Monthly Contribution","default":"0"},"deadline":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Deadline"},"priority":{"type":"integer","maximum":10.0,"minimum":1.0,"title":"Priority","default":1},"category":{"$ref":"#/components/schemas/GoalCategory","default":"custom"},"linked_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Account Id"},"linked_investment_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Investment Account Id"},"shared_with_partner":{"type":"boolean","title":"Shared With Partner","default":false},"joint_goal":{"type":"boolean","title":"Joint Goal","default":false},"partner_link_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partner Link Id"},"split_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Split Type"},"your_percentage":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Your Percentage"},"partner_percentage":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Partner Percentage"}},"type":"object","required":["name","target_amount"],"title":"GoalCreate"},"app__api__goals__GoalResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"target_amount":{"type":"number","title":"Target Amount"},"saved_amount":{"type":"number","title":"Saved Amount"},"effective_saved_amount":{"type":"number","title":"Effective Saved Amount"},"monthly_contribution":{"type":"number","title":"Monthly Contribution"},"deadline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deadline"},"priority":{"type":"integer","title":"Priority"},"category":{"type":"string","title":"Category"},"progress_pct":{"type":"number","title":"Progress Pct"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"},"linked_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Account Id"},"linked_account_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Account Name"},"linked_account_balance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Linked Account Balance"},"linked_investment_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Investment Account Id"},"linked_investment_account_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Investment Account Name"},"linked_investment_account_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Linked Investment Account Value"},"shared_with_partner":{"type":"boolean","title":"Shared With Partner","default":false},"joint_goal":{"type":"boolean","title":"Joint Goal","default":false},"partner_link_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partner Link Id"},"split_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Split Type"},"your_percentage":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Your Percentage"},"partner_percentage":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Partner Percentage"},"owner_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Name"},"is_partner_goal":{"type":"boolean","title":"Is Partner Goal","default":false},"pot_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pot Category"},"milestone":{"anyOf":[{"$ref":"#/components/schemas/GoalMilestone"},{"type":"null"}]},"projection":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Projection"}},"type":"object","required":["id","name","icon","target_amount","saved_amount","effective_saved_amount","monthly_contribution","deadline","priority","category","progress_pct","created_at","updated_at"],"title":"GoalResponse"},"app__api__goals__GoalUpdate":{"properties":{"base_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Base Updated At"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"target_amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Target Amount"},"saved_amount":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Saved Amount"},"monthly_contribution":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Monthly Contribution"},"deadline":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Deadline"},"priority":{"anyOf":[{"type":"integer","maximum":10.0,"minimum":1.0},{"type":"null"}],"title":"Priority"},"category":{"anyOf":[{"$ref":"#/components/schemas/GoalCategory"},{"type":"null"}]},"linked_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Account Id"},"linked_investment_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Investment Account Id"}},"type":"object","title":"GoalUpdate"},"app__api__investments_v2__AccountCreate":{"properties":{"provider":{"type":"string","maxLength":100,"minLength":1,"title":"Provider"},"wrapper_type":{"type":"string","title":"Wrapper Type"},"display_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Display Name"},"is_pension":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Pension"},"link_networth_account_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Link Networth Account Id"},"create_networth":{"type":"boolean","title":"Create Networth","default":true},"planned_monthly":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Planned Monthly"}},"type":"object","required":["provider","wrapper_type"],"title":"AccountCreate"},"app__api__net_worth__AccountCreate":{"properties":{"account_name":{"type":"string","title":"Account Name"},"account_type":{"$ref":"#/components/schemas/NetWorthAccountType"},"balance":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Balance","default":"0"},"currency":{"type":"string","title":"Currency","default":"GBP"},"institution":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Institution"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"interest_rate":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Interest Rate"},"monthly_payment":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Monthly Payment"},"property_value":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Property Value"},"remaining_term_months":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Remaining Term Months"},"rate_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rate Type"},"fixed_rate_end_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fixed Rate End Date"},"planned_monthly":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Planned Monthly"}},"type":"object","required":["account_name","account_type"],"title":"AccountCreate"},"app__api__net_worth__AccountResponse":{"properties":{"id":{"type":"string","title":"Id"},"account_name":{"type":"string","title":"Account Name"},"account_type":{"type":"string","title":"Account Type"},"balance":{"type":"number","title":"Balance"},"currency":{"type":"string","title":"Currency"},"is_manual":{"type":"boolean","title":"Is Manual"},"is_debt":{"type":"boolean","title":"Is Debt"},"last_updated":{"type":"string","title":"Last Updated"},"created_at":{"type":"string","title":"Created At"},"institution":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Institution"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"interest_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Interest Rate"},"monthly_payment":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Monthly Payment"},"property_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Property Value"},"remaining_term_months":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Remaining Term Months"},"rate_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rate Type"},"fixed_rate_end_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fixed Rate End Date"},"ltv_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ltv Ratio"},"remortgage_alert":{"type":"boolean","title":"Remortgage Alert","default":false},"remortgage_months_remaining":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Remortgage Months Remaining"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"represented_by_property_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Represented By Property Id"},"linked_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Account Id"},"linked_investment_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linked Investment Account Id"}},"type":"object","required":["id","account_name","account_type","balance","currency","is_manual","is_debt","last_updated","created_at"],"title":"AccountResponse"},"app__api__openbanking__ConnectRequest":{"properties":{"return_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Return Url"}},"type":"object","title":"ConnectRequest"},"app__api__openbanking__ConnectResponse":{"properties":{"consent_link_id":{"type":"string","title":"Consent Link Id"},"consent_url":{"type":"string","title":"Consent Url"},"customer_id":{"type":"string","title":"Customer Id"}},"type":"object","required":["consent_link_id","consent_url","customer_id"],"title":"ConnectResponse"},"app__api__openbanking__SyncResponse":{"properties":{"synced_accounts":{"type":"integer","title":"Synced Accounts"},"new_transactions":{"type":"integer","title":"New Transactions"},"total_transactions":{"type":"integer","title":"Total Transactions"},"status":{"type":"string","title":"Status","default":"complete"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"retry_after_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Retry After Seconds"},"last_synced_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Synced At"}},"type":"object","required":["synced_accounts","new_transactions","total_transactions"],"title":"SyncResponse"},"app__api__partners__AcceptRequest":{"properties":{"code":{"type":"string","maxLength":6,"minLength":6,"title":"Code"}},"type":"object","required":["code"],"title":"AcceptRequest"},"app__api__partners__GoalCreate":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name"},"target_amount":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Target Amount"},"monthly_contribution":{"anyOf":[{"type":"number","minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"}],"title":"Monthly Contribution","default":"0"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"}},"type":"object","required":["name","target_amount"],"title":"GoalCreate"},"app__api__partners__GoalResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"target_amount":{"type":"number","title":"Target Amount"},"current_amount":{"type":"number","title":"Current Amount"},"user1_contributed":{"type":"number","title":"User1 Contributed"},"user2_contributed":{"type":"number","title":"User2 Contributed"},"monthly_contribution":{"type":"number","title":"Monthly Contribution"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"progress_pct":{"type":"number","title":"Progress Pct"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","name","target_amount","current_amount","user1_contributed","user2_contributed","monthly_contribution","icon","progress_pct","created_at"],"title":"GoalResponse"},"app__api__partners__GoalUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"target_amount":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Target Amount"},"monthly_contribution":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Monthly Contribution"},"contribute_amount":{"anyOf":[{"type":"number"},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Contribute Amount"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"}},"type":"object","title":"GoalUpdate"},"app__api__partners__InviteRequest":{"properties":{"invitee_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invitee Email"}},"type":"object","title":"InviteRequest"},"app__api__partners__InviteResponse":{"properties":{"invite_code":{"type":"string","title":"Invite Code"},"expires_at":{"type":"string","title":"Expires At"}},"type":"object","required":["invite_code","expires_at"],"title":"InviteResponse"},"app__api__payday__SeedResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"rules_created":{"type":"integer","title":"Rules Created"},"detected_payday":{"type":"integer","title":"Detected Payday"}},"type":"object","required":["user_id","rules_created","detected_payday"],"title":"SeedResponse"},"app__api__pots__PotSummary":{"properties":{"key":{"type":"string","title":"Key"},"label":{"type":"string","title":"Label"},"amount":{"type":"number","title":"Amount"},"budget_count":{"type":"integer","title":"Budget Count"},"goal_count":{"type":"integer","title":"Goal Count"},"color":{"type":"string","title":"Color"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},"type":"object","required":["key","label","amount","budget_count","goal_count","color"],"title":"PotSummary"},"app__api__recommendations__ClickResponse":{"properties":{"click_id":{"type":"string","title":"Click Id"},"tracked":{"type":"boolean","title":"Tracked"}},"type":"object","required":["click_id","tracked"],"title":"ClickResponse"},"app__api__referral__ClaimRequest":{"properties":{"referral_code":{"type":"string","title":"Referral Code"}},"type":"object","required":["referral_code"],"title":"ClaimRequest"},"app__api__referral__RedeemRequest":{"properties":{"code":{"type":"string","title":"Code"}},"type":"object","required":["code"],"title":"RedeemRequest"},"app__api__review__MonthlyTrend":{"properties":{"month":{"type":"string","title":"Month"},"spent":{"type":"number","title":"Spent"}},"type":"object","required":["month","spent"],"title":"MonthlyTrend"},"app__api__stripe_billing__SessionResponse":{"properties":{"url":{"type":"string","title":"Url"}},"type":"object","required":["url"],"title":"SessionResponse"},"app__api__subscriptions__CategorySummary":{"properties":{"key":{"type":"string","title":"Key"},"label":{"type":"string","title":"Label"},"icon":{"type":"string","title":"Icon"},"total_monthly":{"type":"number","title":"Total Monthly"},"total_annual":{"type":"number","title":"Total Annual"},"count":{"type":"integer","title":"Count"},"subscriptions":{"items":{"$ref":"#/components/schemas/SubscriptionItem"},"type":"array","title":"Subscriptions"}},"type":"object","required":["key","label","icon","total_monthly","total_annual","count","subscriptions"],"title":"CategorySummary"},"app__api__subscriptions__MonthlyTrend":{"properties":{"month":{"type":"string","title":"Month"},"total":{"type":"number","title":"Total"}},"type":"object","required":["month","total"],"title":"MonthlyTrend"},"app__api__switching__ClickResponse":{"properties":{"click_id":{"type":"string","title":"Click Id"},"tracked":{"type":"boolean","title":"Tracked"},"affiliate_url":{"type":"string","title":"Affiliate Url"}},"type":"object","required":["click_id","tracked","affiliate_url"],"title":"ClickResponse"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}