{"openapi":"3.1.0","info":{"title":"BetterOff API","version":"0.5.0+762e9329","description":"All current tools with complete input schemas and MCP annotations. Response definitions reference /openapi/public.json; that document also includes token-readable GET routes and deprecated aliases."},"servers":[{"url":"https://api.betteroff.finance"}],"components":{"schemas":{"ProblemDetails":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"type":{"type":"string","description":"Always \"about:blank\"; branch on `code`."},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"detail":{"type":"string"},"code":{"type":"string","description":"Stable UPPER_SNAKE code."},"error":{"type":"string","description":"Older clients' copy of `detail`."},"message":{"type":"string","description":"Older clients' copy of `detail`."},"requestId":{"description":"Diagnostic only; quote it to support.","type":"string"},"instance":{"type":"string"},"details":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["type","title","status","detail","code","error","message"],"additionalProperties":{},"description":"RFC 9457 problem details. Some refusals add fields; ignore ones you don't know."},"ToolFailure":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"ok":{"type":"boolean","const":false},"code":{"type":"string","description":"Stable UPPER_SNAKE code."},"error":{"type":"string"},"retryable":{"type":"boolean"},"nextStep":{"type":"string"},"fields":{"description":"The rejected arguments after INVALID_INPUT.","type":"array","items":{"type":"string"}},"requestId":{"description":"Diagnostic only; quote it to support.","type":"string"}},"required":["ok","code","error","retryable","nextStep"],"additionalProperties":{}}},"securitySchemes":{"apiToken":{"type":"http","scheme":"bearer","description":"Personal API token (bo_pat_), created in BetterOff settings with the scopes it may use."},"agentOAuth":{"type":"openIdConnect","openIdConnectUrl":"https://app.betteroff.finance/api/auth/.well-known/openid-configuration","description":"Agent OAuth grant; the same token and scopes as /mcp."}}},"paths":{"/v1/tools/betteroff_search_markets":{"post":{"operationId":"betteroff_search_markets","summary":"Search markets","description":"Use this when the user asks to find public FX reference rates, Hyperliquid spot or perpetual markets, or prediction outcomes. Search public FX reference rates (USD base), Hyperliquid spot/perpetual markets, and prediction markets. Filter by kind or source to narrow coverage. Returns at most 50 dated observations per page, busiest first by 24-hour USD volume where reported. For the next page, pass page.nextCursor as cursor with the same query, kind, source, and limit.","tags":["tools"],"security":[{"agentOAuth":["investments:read"]},{"apiToken":["investments:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"query":{"type":"string","maxLength":120},"kind":{"anyOf":[{"type":"string","enum":["fx","perpetual","spot","prediction"]},{"type":"null"}]},"source":{"anyOf":[{"type":"string","enum":["frankfurter","hyperliquid-perps","hyperliquid-spot","polymarket","polymarket-us","kalshi","pascal"]},{"type":"null"}]},"limit":{"type":"integer","minimum":1,"maximum":50},"offset":{"type":"integer","minimum":0,"maximum":50000},"cursor":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]}},"required":["query","kind","source","limit","offset"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_markets/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_markets/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_markets/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_markets/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_markets/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_markets/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_markets/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_markets/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_markets/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_markets/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_markets/post/responses/default"}}}},"/v1/tools/betteroff_get_overview":{"post":{"operationId":"betteroff_get_overview","summary":"Get overview","description":"Use this when the user asks for a household financial overview or data coverage. Get a compact household picture: latest stored valuation, account coverage, canonical ledger review counts, and the masked login and household name. No provider refresh.","tags":["tools"],"security":[{"agentOAuth":["accounts:read","networth:read"]},{"apiToken":["accounts:read","networth:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_overview/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_overview/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_overview/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_overview/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_overview/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_overview/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_overview/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_overview/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_overview/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_overview/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_overview/post/responses/default"}}}},"/v1/tools/betteroff_get_setup_status":{"post":{"operationId":"betteroff_get_setup_status","summary":"Get setup status","description":"Use this when the user asks what is left to set up, whether billing is active, or which connections need reconnecting. Get this household's BetterOff setup status: billing state, connected-account coverage, and connections that need the user to reconnect. Access issues link to support, not checkout. The user manages connections in BetterOff while signed in; this tool cannot start checkout, connect accounts, or change agent access.","tags":["tools"],"security":[{"agentOAuth":["accounts:read"]},{"apiToken":["accounts:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_setup_status/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_setup_status/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_setup_status/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_setup_status/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_setup_status/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_setup_status/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_setup_status/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_setup_status/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_setup_status/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_setup_status/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_setup_status/post/responses/default"}}}},"/v1/tools/betteroff_list_accounts":{"post":{"operationId":"betteroff_list_accounts","summary":"List accounts","description":"Use this when the user asks which accounts are connected or wants account balances. Get the user's connected accounts with balances, types, and institutions.","tags":["tools"],"security":[{"agentOAuth":["accounts:read"]},{"apiToken":["accounts:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"accountType":{"description":"Filter by account type. Omit or use null to get all accounts.","anyOf":[{"type":"string","enum":["depository","investment","credit","loan","crypto","wallet"]},{"type":"null"}]}},"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_accounts/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_accounts/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_accounts/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_accounts/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_accounts/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_accounts/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_accounts/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_accounts/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_accounts/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_accounts/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_accounts/post/responses/default"}}}},"/v1/tools/betteroff_get_net_worth_history":{"post":{"operationId":"betteroff_get_net_worth_history","summary":"Get net worth history","description":"Use this when the user asks how net worth changed over time. Read stored household valuations over time, paged by cursor. For a two-date explanation use betteroff_explain_net_worth_change.","tags":["tools"],"security":[{"agentOAuth":["networth:read"]},{"apiToken":["networth:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"period":{"anyOf":[{"type":"string","enum":["7d","30d","90d","all"]},{"type":"null"}],"description":"Time period for the trend. Use '7d' for last week, '30d' for last month, '90d' for last quarter, 'all' for all history, or null for '30d'."},"cursor":{"anyOf":[{"type":"object","properties":{"offset":{"type":"integer","minimum":0,"maximum":9007199254740991},"revision":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["offset","revision"]},{"type":"null"}]},"limit":{"anyOf":[{"type":"integer","minimum":1,"maximum":60},{"type":"null"}]}},"required":["period"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_net_worth_history/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_net_worth_history/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_net_worth_history/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_net_worth_history/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_net_worth_history/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_net_worth_history/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_net_worth_history/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_net_worth_history/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_net_worth_history/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_net_worth_history/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_net_worth_history/post/responses/default"}}}},"/v1/tools/betteroff_explain_net_worth_change":{"post":{"operationId":"betteroff_explain_net_worth_change","summary":"Explain net worth change","description":"Use this when the user asks what caused net worth to change between two dates. Reconcile two stored net-worth valuations using asset and liability changes.","tags":["tools"],"security":[{"agentOAuth":["networth:read"]},{"apiToken":["networth:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"startDate":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"endDate":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}},"required":["startDate","endDate"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_explain_net_worth_change/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_explain_net_worth_change/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_explain_net_worth_change/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_explain_net_worth_change/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_explain_net_worth_change/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_explain_net_worth_change/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_explain_net_worth_change/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_explain_net_worth_change/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_explain_net_worth_change/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_explain_net_worth_change/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_explain_net_worth_change/post/responses/default"}}}},"/v1/tools/betteroff_search_transactions":{"post":{"operationId":"betteroff_search_transactions","summary":"Search transactions","description":"Use this when the user asks to find transactions or total a filtered set of transactions. Search transactions by date, merchant, category, trait, type/class, account, or amount; a summary totals all matches. Brokerage deposits/withdrawals: transactionClass `brokerage`, transactionTypes `transfer_in`/`transfer_out`/`deposit`/`withdrawal`.","tags":["tools"],"security":[{"agentOAuth":["transactions:read"]},{"apiToken":["transactions:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"allTime":{"default":null,"description":"Use true for all synced merchant history; dates are ignored. Use it when the answer may be older than the default 30 days: the last or first time, ever, annual or one-off charges, or 'did I pay X before'.","type":["boolean","null"]},"cursor":{"default":null,"anyOf":[{"type":"object","properties":{"offset":{"type":"integer","minimum":0,"maximum":100000},"revision":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["offset","revision"]},{"type":"null"}]},"startDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"Start date (ISO format, e.g. 2025-01-01). Use null for 30 days ago."},"endDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"End date (ISO format). Use null for today."},"merchant":{"description":"Merchant name to search for (partial match).","type":["string","null"]},"traits":{"anyOf":[{"type":"array","items":{"type":"string","enum":["discretionary","travel","health","kids","gifts","charity","business","crypto"]}},{"type":"null"}],"description":"Only transactions whose merchant has every listed trait. Use for purposes a category does not capture. discretionary: optional spending: dining out, entertainment, hobbies, shopping for wants; travel: trips: flights, hotels, rental cars, cruises, travel booking; health: medical care: doctors, dentists, pharmacies, vision, therapy; kids: children: childcare, schools, tutoring, toys, kids' activities; gifts: gifts: florists, gift shops, gift cards; charity: donations: charities, nonprofits, religious organizations, fundraisers; business: work expenses: software, office supplies, coworking, professional services; crypto: crypto: exchanges, on-ramps, wallets, crypto cards. Person-to-person payments and unrecognized merchants carry no traits. Use null for no trait filter."},"category":{"description":"Category code (e.g. FOOD_AND_DRINK, TRANSPORTATION, ENTERTAINMENT).","type":["string","null"]},"transactionTypes":{"anyOf":[{"type":"array","items":{"type":"string","enum":["bank_deposit","bank_withdrawal","card_charge","card_refund","ach_transfer","wire","check","atm","cash","interest_payment","fee","buy","sell","short_sell","buy_to_cover","swap","dividend","qualified_dividend","capital_gain_distribution","return_of_capital","interest","bond_coupon","airdrop","fork","staking_reward","mining_reward","lending_reward","nft_mint","nft_sale","nft_purchase","lp_mint","lp_burn","lending_supply","lending_borrow","lending_repay","transfer","bridge_out","bridge_in","split","spin_off","merger_proceeds","rights_issue","manual_valuation_change","other","payment","refund","deposit","withdrawal","receive","send","transfer_in","transfer_out"]}},{"type":"null"}],"description":"Filter by transaction type. For investment account deposits/withdrawals, use transfer_in/deposit/bank_deposit for deposits and transfer_out/withdrawal/bank_withdrawal for withdrawals."},"transactionClass":{"anyOf":[{"type":"string","enum":["bank","brokerage","crypto_exchange","blockchain_wallet"]},{"type":"null"}],"description":"Filter by normalized transaction class. Use brokerage for investment accounts."},"accountId":{"description":"Filter to a specific account by ID. Use null to search all accounts.","type":["string","null"]},"minAmount":{"description":"Minimum transaction amount.","type":["number","null"]},"maxAmount":{"description":"Maximum transaction amount.","type":["number","null"]},"limit":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Max results to return (default 25, max 50). Use null for 25."}},"required":["startDate","endDate","merchant","traits","category","transactionTypes","transactionClass","accountId","minAmount","maxAmount","limit"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_transactions/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_transactions/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_transactions/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_transactions/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_transactions/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_transactions/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_transactions/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_transactions/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_transactions/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_transactions/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_transactions/post/responses/default"}}}},"/v1/tools/betteroff_analyze_spending":{"post":{"operationId":"betteroff_analyze_spending","summary":"Analyze spending","description":"Use this when the user asks where money went or compares spending across periods. Read category or merchant spending for a period, optionally against an earlier one. Excludes transfers and loan payments; fees and interest count.","tags":["tools"],"security":[{"agentOAuth":["transactions:read"]},{"apiToken":["transactions:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"groupBy":{"type":"string","enum":["category","merchant"]},"startDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"Start date (ISO). Use null for start of current month."},"endDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"End date (ISO). Use null for today."},"comparison":{"anyOf":[{"type":"object","properties":{"startDate":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"endDate":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"}},"required":["startDate","endDate"]},{"type":"null"}]}},"required":["startDate","endDate","comparison"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_analyze_spending/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_analyze_spending/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_analyze_spending/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_analyze_spending/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_analyze_spending/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_analyze_spending/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_analyze_spending/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_analyze_spending/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_analyze_spending/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_analyze_spending/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_analyze_spending/post/responses/default"}}}},"/v1/tools/betteroff_detect_spending_patterns":{"post":{"operationId":"betteroff_detect_spending_patterns","summary":"Detect spending patterns","description":"Use this when the user asks about spending habits, trends, or unusual transactions. Detect spending patterns: frequent merchants, complete-month trends, and unusual transactions (monthly repeats such as rent excluded). Frequent merchants are habits, not bills; use betteroff_list_recurring for recurring charges.","tags":["tools"],"security":[{"agentOAuth":["transactions:read"]},{"apiToken":["transactions:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"startDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"Start date (ISO). Use null for 6 months ago."},"endDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"End date (ISO). Use null for today."}},"required":["startDate","endDate"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_detect_spending_patterns/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_detect_spending_patterns/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_detect_spending_patterns/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_detect_spending_patterns/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_detect_spending_patterns/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_detect_spending_patterns/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_detect_spending_patterns/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_detect_spending_patterns/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_detect_spending_patterns/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_detect_spending_patterns/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_detect_spending_patterns/post/responses/default"}}}},"/v1/tools/betteroff_get_account_flows":{"post":{"operationId":"betteroff_get_account_flows","summary":"Get account flows","description":"Use this when the user asks how much entered or left specific accounts. Gross inflows, gross outflows, and net flow for selected accounts over a date range, aggregated over ALL matches server-side, e.g. 'how much did I deposit into Schwab this year'. Prefer this over betteroff_search_transactions for deposit/withdrawal totals.","tags":["tools"],"security":[{"agentOAuth":["accounts:read","transactions:read"]},{"apiToken":["accounts:read","transactions:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"startDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"Start date (ISO format, e.g. 2026-01-01). Use null for Jan 1 of this year."},"endDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"End date (ISO format). Use null for today."},"accountIds":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific account IDs to include. Use null to select by accountType/institution."},"accountType":{"anyOf":[{"type":"string","enum":["depository","investment","credit","loan","crypto","wallet"]},{"type":"null"}],"description":"Optional account type filter. Use investment for brokerage/retirement accounts."},"institution":{"description":"Optional institution name filter, e.g. Charles Schwab. Partial matches are accepted.","type":["string","null"]},"direction":{"anyOf":[{"type":"string","enum":["all","inflow","outflow"]},{"type":"null"}],"description":"Use inflow for deposits only, outflow for withdrawals only, all for both."},"limit":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Max transaction rows to return for evidence (default 25, max 100)."}},"required":["startDate","endDate","accountIds","accountType","institution","direction","limit"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_account_flows/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_account_flows/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_account_flows/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_account_flows/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_account_flows/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_account_flows/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_account_flows/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_account_flows/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_account_flows/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_account_flows/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_account_flows/post/responses/default"}}}},"/v1/tools/betteroff_get_cash_flow":{"post":{"operationId":"betteroff_get_cash_flow","summary":"Get cash flow","description":"Use this when the user asks about income, expenses, or cash flow. Get income vs expenses for a period with prior-period comparison and projections. Use for cash flow, earned vs spent, or saving questions.","tags":["tools"],"security":[{"agentOAuth":["cashflow:read"]},{"apiToken":["cashflow:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"startDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"Start date (ISO). Use null for start of current month."},"endDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"End date (ISO). Use null for today."}},"required":["startDate","endDate"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_cash_flow/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_cash_flow/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_cash_flow/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_cash_flow/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_cash_flow/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_cash_flow/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_cash_flow/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_cash_flow/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_cash_flow/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_cash_flow/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_cash_flow/post/responses/default"}}}},"/v1/tools/betteroff_list_recurring":{"post":{"operationId":"betteroff_list_recurring","summary":"List recurring","description":"Use this when the user asks about recurring bills, subscriptions, or income. Get Plaid-reported recurring streams (active, early, inactive). Not a payment history (use search_transactions) or proof of insurance coverage.","tags":["tools"],"security":[{"agentOAuth":["cashflow:read"]},{"apiToken":["cashflow:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_recurring/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_recurring/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_recurring/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_recurring/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_recurring/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_recurring/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_recurring/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_recurring/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_recurring/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_recurring/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_recurring/post/responses/default"}}}},"/v1/tools/betteroff_get_portfolio":{"post":{"operationId":"betteroff_get_portfolio","summary":"Get portfolio","description":"Use this when the user asks about investment holdings, allocation, or concentration. Read portfolio positions, allocation, and concentration for the full filtered portfolio. includePositions false returns the allocation summary; true pages positions by cursor.","tags":["tools"],"security":[{"agentOAuth":["investments:read"]},{"apiToken":["investments:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"symbol":{"description":"Filter by ticker symbol (e.g. AAPL, BTC, ETH). Use null for all symbols.","type":["string","null"]},"instrumentId":{"description":"Filter by canonical instrument ID. Preferred over symbol when available. Use null for all.","type":["string","null"]},"type":{"description":"Filter by holding type (equity, etf, mutual_fund, crypto). Use null for all types.","type":["string","null"]},"groupBy":{"type":"string","enum":["type","account","symbol","instrument","underlying"],"description":"Group by type, account, symbol, separate instrument, or underlying ISIN exposure across brokerage holdings and Stock Tokens."},"includePositions":{"type":"boolean"},"cursor":{"anyOf":[{"type":"object","properties":{"offset":{"type":"integer","minimum":0,"maximum":9007199254740991},"revision":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["offset","revision"]},{"type":"null"}]},"limit":{"anyOf":[{"type":"integer","minimum":1,"maximum":50},{"type":"null"}]}},"required":["symbol","instrumentId","type","groupBy","includePositions","limit"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_portfolio/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_portfolio/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_portfolio/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_portfolio/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_portfolio/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_portfolio/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_portfolio/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_portfolio/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_portfolio/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_portfolio/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_portfolio/post/responses/default"}}}},"/v1/tools/betteroff_get_defi_positions":{"post":{"operationId":"betteroff_get_defi_positions","summary":"Get defi positions","description":"Use this when the user asks about DeFi, lending, staking, or LP positions, or protocol exposure. DeFi exposure by protocol across chains: total value, position count, per-asset breakdown.","tags":["tools"],"security":[{"agentOAuth":["investments:read"]},{"apiToken":["investments:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"protocol":{"description":"Filter to a specific protocol name (case-insensitive substring match, e.g. 'aave', 'uniswap'). Use null for all protocols.","type":["string","null"]},"chain":{"description":"Filter to a specific chain slug (e.g. 'ethereum', 'base', 'arbitrum'). Use null for all chains.","type":["string","null"]}},"required":["protocol","chain"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_defi_positions/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_defi_positions/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_defi_positions/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_defi_positions/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_defi_positions/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_defi_positions/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_defi_positions/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_defi_positions/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_defi_positions/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_defi_positions/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_defi_positions/post/responses/default"}}}},"/v1/tools/betteroff_get_vault_yields":{"post":{"operationId":"betteroff_get_vault_yields","summary":"Get vault yields","description":"Use this when the user asks for current APYs of the vaults Investing lists. List reported APYs for the Morpho vaults the user can deposit into from BetterOff Investing: USDC and USDT on Ethereum, USDC on Base, and pathUSD on Tempo. Each row has the protocol's source and date. Filter by venue or asset symbol. Returns at most 50 vaults in name order.","tags":["tools"],"security":[{"agentOAuth":["investments:read"]},{"apiToken":["investments:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"venue":{"type":"string","enum":["upshift","morpho","ethena"]},"asset":{"description":"Asset symbol such as USDC.","type":"string","maxLength":20}},"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_vault_yields/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_vault_yields/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_vault_yields/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_vault_yields/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_vault_yields/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_vault_yields/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_vault_yields/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_vault_yields/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_vault_yields/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_vault_yields/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_vault_yields/post/responses/default"}}}},"/v1/tools/betteroff_list_debts":{"post":{"operationId":"betteroff_list_debts","summary":"List debts","description":"Use this when the user asks what they owe or which debt terms are missing. Get the user's debts (cards and loans): names with last digits, balances with balanceAsOf, APRs, minimum payments, and totals. Use for debt, interest rate, or payoff-priority questions.","tags":["tools"],"security":[{"agentOAuth":["debts:read"]},{"apiToken":["debts:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_debts/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_debts/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_debts/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_debts/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_debts/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_debts/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_debts/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_debts/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_debts/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_debts/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_debts/post/responses/default"}}}},"/v1/tools/betteroff_simulate_debt_payoff":{"post":{"operationId":"betteroff_simulate_debt_payoff","summary":"Simulate debt payoff","description":"Use this when the user asks to compare debt payoff strategies. Simulate paying off debts by avalanche (highest APR first) or snowball (smallest balance first), with an optional extra monthly payment. Refuses with missingInputs when a balance, APR, minimum payment, or FX rate is missing; betteroff_propose_debt_details saves terms the user states. Read-only; never moves money.","tags":["tools"],"security":[{"agentOAuth":["debts:read"]},{"apiToken":["debts:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"strategy":{"type":"string","enum":["avalanche","snowball"],"description":"avalanche = highest APR first (minimizes interest); snowball = smallest balance first (faster early wins)."},"extraMonthly":{"type":"number","minimum":0,"maximum":1000000,"description":"Extra amount paid toward debts each month beyond the minimums, in the user's base currency. Use 0 for none."}},"required":["strategy","extraMonthly"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_simulate_debt_payoff/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_simulate_debt_payoff/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_simulate_debt_payoff/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_simulate_debt_payoff/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_simulate_debt_payoff/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_simulate_debt_payoff/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_simulate_debt_payoff/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_simulate_debt_payoff/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_simulate_debt_payoff/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_simulate_debt_payoff/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_simulate_debt_payoff/post/responses/default"}}}},"/v1/tools/betteroff_get_checklist":{"post":{"operationId":"betteroff_get_checklist","summary":"Get checklist","description":"Use this when the user asks what to do next, how prepared the household is, or about insurance, estate documents, an emergency fund, retirement accounts, or credit freezes; for an explicit saved tax-review request, use includeTaxReviews to read current scoped results. Get the household's readiness checklist: 0-100 score, 30-day change, and each item's status, evidence, and points. Edits happen in BetterOff. Set includeTaxReviews only for an explicit request to read saved tax reviews; summaries use current saved facts.","tags":["tools"],"security":[{"agentOAuth":["checklist:read"]},{"apiToken":["checklist:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"includeTaxReviews":{"type":"boolean"}},"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_checklist/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_checklist/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_checklist/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_checklist/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_checklist/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_checklist/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_checklist/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_checklist/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_checklist/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_checklist/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_checklist/post/responses/default"}}}},"/v1/tools/betteroff_search_activity":{"post":{"operationId":"betteroff_search_activity","summary":"Search activity","description":"Use this when the user asks about recorded account changes or correction proposals. Read permitted record changes. For an account's correction proposals (pending or approved), set accountId (via betteroff_list_accounts), actorType=all, action=null; needs corrections:prepare. Omits security events and raw fields.","tags":["tools"],"security":[{"agentOAuth":["activity:read"]},{"apiToken":["activity:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"accountId":{"default":null,"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"actorType":{"type":"string","enum":["agent","user","system","all"]},"action":{"anyOf":[{"type":"string","enum":["categorize_transaction","update_transaction","classify_recurring","confirm_debt_details","apply_correction","undo_correction"]},{"type":"null"}]},"limit":{"anyOf":[{"type":"integer","minimum":1,"maximum":50},{"type":"null"}]},"before":{"default":null,"anyOf":[{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["timestamp","id"]},{"type":"null"}]}},"required":["actorType","action","limit"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_activity/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_activity/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_activity/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_activity/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_activity/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_activity/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_activity/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_activity/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_activity/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_activity/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_search_activity/post/responses/default"}}}},"/v1/tools/betteroff_list_observations":{"post":{"operationId":"betteroff_list_observations","summary":"List observations","description":"Use this when the user asks about recorded financial findings and their status. Read recorded household financial findings and their status. Excludes insurance checklist findings. Does not refresh or dismiss findings.","tags":["tools"],"security":[{"agentOAuth":["accounts:read","networth:read","transactions:read","cashflow:read","investments:read","debts:read"]},{"apiToken":["accounts:read","networth:read","transactions:read","cashflow:read","investments:read","debts:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"status":{"anyOf":[{"type":"string","enum":["open","snoozed","dismissed","resolved"]},{"type":"null"}]},"limit":{"anyOf":[{"type":"integer","minimum":1,"maximum":30},{"type":"null"}]},"before":{"anyOf":[{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["timestamp","id"]},{"type":"null"}]}},"required":["status","limit","before"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_observations/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_observations/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_observations/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_observations/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_observations/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_observations/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_observations/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_observations/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_observations/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_observations/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_list_observations/post/responses/default"}}}},"/v1/tools/betteroff_propose_category_change":{"post":{"operationId":"betteroff_propose_category_change","summary":"Propose category change","description":"Use this when the user asks to correct the category of selected transactions. Prepare a durable category correction for selected transaction IDs. This saves a pending proposal and changes no financial records. The user must open the authenticated review link and explicitly choose selected payments or matching and future payments. Never report a proposal as applied.","tags":["tools"],"security":[{"agentOAuth":["transactions:read","corrections:prepare"]},{"apiToken":["transactions:read","corrections:prepare"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"transactionIds":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"category":{"type":"string","enum":["FOOD_AND_DRINK","RENT_AND_UTILITIES","ENTERTAINMENT","GENERAL_MERCHANDISE","GENERAL_SERVICES","PEER_PAYMENTS","TRANSPORTATION","TRAVEL","PERSONAL_CARE","MEDICAL","EDUCATION","INSURANCE","GIFTS_AND_DONATIONS","PETS","SUBSCRIPTIONS","REAL_ESTATE","INCOME","LOAN_PAYMENTS","TRANSFER_IN","TRANSFER_OUT","BANK_FEES","GOVERNMENT_AND_NON_PROFIT","HOME_IMPROVEMENT","OTHER"]}},"required":["transactionIds","category"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_category_change/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_category_change/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_category_change/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_category_change/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_category_change/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_category_change/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_category_change/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_category_change/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_category_change/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_category_change/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_category_change/post/responses/default"}}}},"/v1/tools/betteroff_propose_recurring_kind":{"post":{"operationId":"betteroff_propose_recurring_kind","summary":"Propose recurring kind","description":"Use this when the user says a recurring payment should be a bill or a subscription, for example that a Zelle payment is rent. Propose marking one of the user's recurring outgoing payments as a bill or a subscription. Get the streamId first with betteroff_list_recurring. This tool changes nothing: the user opens the review link and approves it in BetterOff. Never say the change is done.","tags":["tools"],"security":[{"agentOAuth":["cashflow:read","corrections:prepare"]},{"apiToken":["cashflow:read","corrections:prepare"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"streamId":{"type":"string","minLength":1,"maxLength":200,"description":"The streamId from betteroff_list_recurring."},"kind":{"type":"string","enum":["bill","subscription"],"description":"What the payment should be marked as."}},"required":["streamId","kind"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_recurring_kind/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_recurring_kind/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_recurring_kind/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_recurring_kind/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_recurring_kind/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_recurring_kind/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_recurring_kind/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_recurring_kind/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_recurring_kind/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_recurring_kind/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_recurring_kind/post/responses/default"}}}},"/v1/tools/betteroff_propose_debt_details":{"post":{"operationId":"betteroff_propose_debt_details","summary":"Propose debt details","description":"Use this when the user provides a debt's APR, minimum payment, or next due date to save. Propose saving debt details the user states in chat: APR, minimum payment, or next due date, e.g. 'my Chase card APR is 24.99%'. Pass debtId from betteroff_list_debts, else the debt name. Use only numbers the user stated. This changes nothing until the user approves it at the review link; never say it is done.","tags":["tools"],"security":[{"agentOAuth":["debts:read","corrections:prepare"]},{"apiToken":["debts:read","corrections:prepare"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"debtId":{"description":"The debt's id from betteroff_list_debts. Preferred over debtName.","anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"debtName":{"description":"The debt's name as betteroff_list_debts returns it. Null when debtId is given.","anyOf":[{"type":"string","minLength":1,"maxLength":200},{"type":"null"}]},"interestRate":{"anyOf":[{"type":"number","minimum":0,"maximum":100},{"type":"null"}],"description":"APR as a percent, e.g. 24.99. Null to leave it unchanged."},"minimumPayment":{"anyOf":[{"type":"number","minimum":0,"maximum":1000000},{"type":"null"}],"description":"Minimum monthly payment. Null to leave it unchanged."},"nextPaymentDueDate":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"Next due date as YYYY-MM-DD. Null to leave it unchanged."}},"required":["interestRate","minimumPayment","nextPaymentDueDate"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_debt_details/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_debt_details/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_debt_details/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_debt_details/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_debt_details/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_debt_details/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_debt_details/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_debt_details/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_debt_details/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_debt_details/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_propose_debt_details/post/responses/default"}}}},"/v1/tools/betteroff_request_transfer":{"post":{"operationId":"betteroff_request_transfer","summary":"Request transfer","description":"Use this when the user asks to move USDC between two of their own tracked wallets on Solana. Request a USDC transfer on Solana between two wallets this household tracks. Saves a request for the user to review; never approves, signs, or sends. Return the review link and say it awaits the user's approval and wallet signature.","tags":["tools"],"security":[{"agentOAuth":["accounts:read","transfers:prepare"]},{"apiToken":["accounts:read","transfers:prepare"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"chain":{"type":"string","enum":["solana","base"],"description":"Use solana. Base transfer requests are paused."},"fromWallet":{"type":"string","maxLength":64,"description":"Source wallet address tracked by this household."},"toWallet":{"type":"string","maxLength":64,"description":"Destination wallet address tracked by this household."},"amountUsdc":{"type":"string","pattern":"^\\d{1,9}(\\.\\d{1,6})?$","description":"USDC amount as a decimal string, at most 6 decimals."},"idempotencyKey":{"description":"Required for outside agents. Reuse the same key when retrying the same request; use a new key for a new one.","type":"string","pattern":"^[A-Za-z0-9_-]{8,100}$"}},"required":["chain","fromWallet","toWallet","amountUsdc"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_transfer/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_transfer/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_transfer/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_transfer/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_transfer/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_transfer/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_transfer/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_transfer/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_transfer/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_transfer/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_transfer/post/responses/default"}}}},"/v1/tools/betteroff_request_bank_transfer":{"post":{"operationId":"betteroff_request_bank_transfer","summary":"Request bank transfer","description":"Use this when the user asks to move money between two of their own bank or brokerage accounts linked in Banking. Request a bank transfer through Natural between two of the user's own accounts linked in BetterOff Banking. Call without account IDs or amount to list the accounts and the per-transfer cap. Saves a request for the user to review; never approves or starts the transfer. Return the review link and say it awaits the user's passkey approval.","tags":["tools"],"security":[{"agentOAuth":["accounts:read","transfers:bank"]},{"apiToken":["accounts:read","transfers:bank"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"sourceAccountId":{"description":"Natural account ID to pull from, from this tool's account list.","type":"string","maxLength":64},"destinationAccountId":{"description":"Natural account ID to send to, from this tool's account list.","type":"string","maxLength":64},"amountUsd":{"description":"US dollar amount as a decimal string, at most 2 decimals.","type":"string","pattern":"^\\d{1,7}(\\.\\d{1,2})?$"},"idempotencyKey":{"description":"Required for outside agents. Reuse the same key when retrying the same request; use a new key for a new one.","type":"string","pattern":"^[A-Za-z0-9_-]{8,100}$"}},"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_bank_transfer/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_bank_transfer/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_bank_transfer/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_bank_transfer/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_bank_transfer/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_bank_transfer/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_bank_transfer/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_bank_transfer/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_bank_transfer/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_bank_transfer/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_bank_transfer/post/responses/default"}}}},"/v1/tools/betteroff_request_vault_deposit":{"post":{"operationId":"betteroff_request_vault_deposit","summary":"Request vault deposit","description":"Use this when the user asks to deposit USDC, USDT, or pathUSD from one of their own wallets into a vault they chose from Investing. Request a USDC, USDT, or pathUSD deposit from one of the household's tracked EVM wallets into a Morpho vault on Ethereum, Base, or Tempo listed by betteroff_get_vault_yields. Saves a request for the user to review; never approves, signs, or deposits. Only prepare a deposit the user asked for, into a vault the user named; never pick a vault for them. Return the review link and say it awaits the user's approval and wallet signature.","tags":["tools"],"security":[{"agentOAuth":["investments:read","transfers:vault"]},{"apiToken":["investments:read","transfers:vault"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"vault":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Vault address from betteroff_get_vault_yields."},"chainId":{"description":"The vault's chainId from betteroff_get_vault_yields; needed when an address is listed on two chains.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"fromWallet":{"type":"string","pattern":"^0x[0-9a-fA-F]{40}$","description":"Household wallet that holds the vault's deposit asset."},"amountUsd":{"type":"string","pattern":"^\\d{1,9}(\\.\\d{1,6})?$","description":"Dollar amount as a decimal string, at most 6 decimals."},"idempotencyKey":{"description":"Required for outside agents. Reuse the same key when retrying the same request; use a new key for a new one.","type":"string","pattern":"^[A-Za-z0-9_-]{8,100}$"}},"required":["vault","fromWallet","amountUsd"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_vault_deposit/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_vault_deposit/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_vault_deposit/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_vault_deposit/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_vault_deposit/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_vault_deposit/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_vault_deposit/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_vault_deposit/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_vault_deposit/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_vault_deposit/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_request_vault_deposit/post/responses/default"}}}},"/v1/tools/betteroff_get_action_request":{"post":{"operationId":"betteroff_get_action_request","summary":"Get action request","description":"Use this when the user asks whether a requested transfer was approved, sent, or confirmed. Read a USDC transfer, bank transfer, or vault deposit request's status from BetterOff's records.","tags":["tools"],"security":[{"agentOAuth":["transfers:read"]},{"apiToken":["transfers:read"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"requestId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["requestId"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_action_request/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_action_request/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_action_request/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_action_request/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_action_request/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_action_request/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_action_request/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_action_request/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_action_request/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_action_request/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_get_action_request/post/responses/default"}}}},"/v1/tools/betteroff_cancel_action_request":{"post":{"operationId":"betteroff_cancel_action_request","summary":"Cancel action request","description":"Use this when the user asks to cancel a transfer request before signing it. Cancel a USDC transfer, bank transfer, or vault deposit request before the user signs or approves it.","tags":["tools"],"security":[{"agentOAuth":["transfers:prepare"]},{"apiToken":["transfers:prepare"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":false},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"requestId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["requestId"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_cancel_action_request/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_cancel_action_request/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_cancel_action_request/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_cancel_action_request/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_cancel_action_request/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_cancel_action_request/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_cancel_action_request/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_cancel_action_request/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_cancel_action_request/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_cancel_action_request/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_cancel_action_request/post/responses/default"}}}},"/v1/tools/betteroff_submit_feedback":{"post":{"operationId":"betteroff_submit_feedback","summary":"Submit feedback","description":"Send a diagnostic report to BetterOff support only when the user requests or approves sending it. Creates a support case, not a financial correction. Never send conversation history, balances, transactions, tool payloads, or credentials. Reuse the idempotency key when retrying. Returns a receipt, not a promise of resolution.","tags":["tools"],"security":[{"agentOAuth":["feedback:submit"]},{"apiToken":["feedback:submit"]}],"x-stability":"beta","x-mcp-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":false,"idempotentHint":true},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"category":{"type":"string","enum":["bug","confusing_result","missing_capability","suggestion"]},"description":{"type":"string","minLength":1,"maxLength":1000,"description":"User-approved diagnostic summary. Exclude financial data, credentials, conversation history, and tool payloads."},"toolName":{"type":"string","pattern":"^betteroff_[a-z_]{1,80}$"},"requestId":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,128}$"},"client":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[A-Za-z0-9 ._+-]+$"},"clientVersion":{"type":"string","minLength":1,"maxLength":40,"pattern":"^[A-Za-z0-9 ._+-]+$"},"idempotencyKey":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Generate once per report; reuse for every retry."},"userApproved":{"type":"boolean","const":true,"description":"True only after the user requests or approves sending this report."}},"required":["category","description","idempotencyKey","userApproved"],"additionalProperties":false}}}},"responses":{"200":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_submit_feedback/post/responses/200"},"400":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_submit_feedback/post/responses/400"},"401":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_submit_feedback/post/responses/401"},"402":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_submit_feedback/post/responses/402"},"403":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_submit_feedback/post/responses/403"},"404":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_submit_feedback/post/responses/404"},"409":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_submit_feedback/post/responses/409"},"422":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_submit_feedback/post/responses/422"},"429":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_submit_feedback/post/responses/429"},"503":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_submit_feedback/post/responses/503"},"default":{"$ref":"https://api.betteroff.finance/openapi/public.json#/paths/~1v1~1tools~1betteroff_submit_feedback/post/responses/default"}}}}}}