# WealthTools — Full API Reference for LLMs > Free, professional-grade personal finance calculators accessible via a free REST API. Every endpoint requires an API key — get an instant free guest key with no signup, or a higher-limit personal key by signing in. WealthTools provides financial modeling tools for investment projections, mortgage calculations, credit card payoff timelines, net worth tracking, and budget management. Every endpoint, calculators included, requires an API key. ## API Overview - Base URL: https://wealth-tools.com/api/v1 - Docs (Swagger UI): https://wealth-tools.com/api/docs - OpenAPI spec (JSON): https://wealth-tools.com/api/openapi - Agent metadata: https://wealth-tools.com/.well-known/agent.json - Pricing: Free - Authentication (always required): `Authorization: Bearer YOUR_API_KEY` - **If you don't have a key**: `POST /api/v1/guest-key` with no request body returns `{"api_key": "wt_..."}` instantly, no signup. Use that key on every subsequent call. Rate limit: 20 requests/hour. - **Personal key**: a human signs in and generates one at https://wealth-tools.com/users/settings. Rate limit: 1,000 requests/hour. - Content-Type: application/json --- ## POST /api/v1/calculators/investments Projects compound investment growth over time across one or more accounts, with support for tax-deferred, Roth, and taxable accounts. ### Request ```json { "accounts": [ { "name": "401k", "balance": 50000, "annual_contribution": 18000, "growth_rate": 7, "account_type": "tax_deferred", "tax_rate": 22 }, { "name": "Roth IRA", "balance": 20000, "annual_contribution": 7000, "growth_rate": 7, "account_type": "roth" } ], "end_year": 2045 } ``` ### Response ```json { "total_final_value": 1250000.0, "total_contributions": 450000.0, "total_growth": 800000.0, "projection_years": 20, "accounts": [ { "account_name": "401k", "initial_balance": 50000.0, "monthly_contribution": 1500.0, "final_value": 900000.0, "after_tax_value": 702000.0, "total_contributions": 360000.0, "total_growth": 540000.0, "investment_schedule": [ { "period": 2025, "starting_balance": 50000.0, "ending_balance": 57500.0, "growth_rate": 7.0, "monthly_contribution": 1500.0, "tax_rate": 22.0, "after_tax_value": 44850.0, "model_id": null } ] } ] } ``` --- ## POST /api/v1/calculators/mortgage Calculates monthly mortgage payments, total interest paid, and loan details. ### Request ```json { "home_value": 400000, "down_payment_percent": 20, "interest_rate": 6.5, "term_years": 30, "property_taxes": 4800, "homeowners_insurance": 1200, "hoa_fees": 0 } ``` Required: `home_value`, `down_payment_percent`, `interest_rate` Optional: `term_years` (default 30), `property_taxes`, `homeowners_insurance`, `hoa_fees` ### Response ```json { "home_value": 400000.0, "loan_amount": 320000.0, "monthly_principal_and_interest": 2022.62, "total_monthly_payment": 2522.62, "total_interest_paid": 408140.61, "interest_rate": 6.5, "term_years": 30 } ``` --- ## POST /api/v1/calculators/credit-card-repayment Calculates how long it will take to pay off a credit card balance and total interest paid. ### Request ```json { "balance": 5000, "annual_rate": 18.99, "monthly_payment": 200 } ``` Required: `balance`, `annual_rate`, `monthly_payment` ### Response ```json { "initial_balance": 5000.0, "monthly_payment": 200.0, "months_to_payoff": 31, "years_to_payoff": 2.6, "total_interest_paid": 1079.42, "total_amount_paid": 6079.42, "payoff_date": "2027-08-15", "monthly_payment_schedule": [ { "month": 1, "starting_balance": "5000", "ending_balance": "4879.13", "total_payment": "200.00", "principal_payment": "120.87", "interest_charge": "79.13", "total_interest_paid": "79.13" } ], "yearly_payment_schedule": [ { "year": 1, "months_in_year": 12, "starting_balance": "5000", "ending_balance": "3416.36", "total_payments": "2400.00", "total_principal": "1583.64", "total_interest": "816.36" } ] } ``` --- ## POST /api/v1/calculators/net-worth Calculates current net worth from a list of assets and liabilities, with optional multi-year projections. ### Request ```json { "assets": [ { "name": "Primary Residence", "value": 650000, "growth_rate": 3, "type": "home_equity" }, { "name": "401k", "value": 250000, "growth_rate": 7, "type": "investment_account", "monthly_contribution": 1500, "tax_deferred": true, "tax_rate": 22, "tax_deferred_until": 2045 }, { "name": "Roth IRA", "value": 150000, "growth_rate": 7, "type": "investment_account", "monthly_contribution": 500 }, { "name": "Emergency Fund", "value": 50000, "growth_rate": 2, "type": "bank_account" } ], "liabilities": [ { "name": "Mortgage", "amount": 400000, "interest_rate": 4, "type": "mortgage", "min_monthly_payment": 2400 }, { "name": "Auto Loan", "amount": 25000, "interest_rate": 5, "type": "loan", "min_monthly_payment": 450 } ], "projection_years": 10 } ``` Asset types: `investment_account`, `bank_account`, `home_equity`, `other` Liability types: `mortgage`, `loan`, `credit_card`, `personal_loan`, `student_loan`, `medical_debt`, `auto_loan`, `line_of_credit`, `other` Required per asset: `name`, `value`, `growth_rate` Required per liability: `name`, `amount` ### Response ```json { "current_net_worth": 625000.0, "total_assets": 1050000.0, "total_liabilities": 425000.0, "projection_years": 10, "projections": [ { "year": 1, "total_assets": "1228375.000", "total_liabilities": "442250.00", "net_worth": "786125.000" }, { "year": 5, "total_assets": "1472509.380", "total_liabilities": "518568.200", "net_worth": "953941.180" }, { "year": 10, "total_assets": "1862141.220", "total_liabilities": "632820.080", "net_worth": "1229321.140" } ] } ``` --- ## POST /api/v1/calculators/debt-payoff Compares the debt avalanche (highest interest rate first) and debt snowball (smallest balance first) strategies for a set of debts against a minimum-payments-only baseline. Every debt keeps receiving its own minimum payment; `extra_monthly_payment` (plus whatever's freed up as each debt is paid off) rolls entirely into whichever debt is highest priority under each strategy. ### Request ```json { "debts": [ { "name": "Chase Sapphire", "balance": 4500, "interest_rate": 22.99, "min_monthly_payment": 120 }, { "name": "Car Loan", "balance": 12000, "interest_rate": 6.5, "min_monthly_payment": 320 } ], "extra_monthly_payment": 200 } ``` Required per debt: `name`, `balance`, `interest_rate`, `min_monthly_payment` Optional: `extra_monthly_payment` (defaults to 0) ### Response ```json { "baseline": { "months_to_payoff": 42, "total_interest_paid": 3218.55 }, "avalanche": { "months_to_payoff": 27, "total_interest_paid": 1802.10, "months_saved": 15, "interest_saved": 1416.45, "payoff_order": ["Chase Sapphire", "Car Loan"] }, "snowball": { "months_to_payoff": 28, "total_interest_paid": 1889.40, "months_saved": 14, "interest_saved": 1329.15, "payoff_order": ["Chase Sapphire", "Car Loan"] } } ``` `months_to_payoff` and `total_interest_paid` are `null` if the budget never covers the combined minimum payments. `months_saved` and `interest_saved` are `null` when a strategy doesn't actually beat the baseline. --- ## Debt Accounts Debt accounts are the loans, credit cards, and other liabilities tracked by the Debt Payoff Planner — scoped to the authenticated user (personal or guest key). They're the same underlying accounts used by the Net Worth Calculator, filtered to debt types. ### GET /api/v1/debts Lists the user's debt accounts. ### Response ```json { "data": [ { "id": 42, "name": "Chase Sapphire", "type": "credit_card", "balance": 4500.0, "interest_rate": 22.99, "min_monthly_payment": 120.0 } ] } ``` ### POST /api/v1/debts Adds a new debt account. ### Request ```json { "name": "Chase Sapphire", "type": "credit_card", "balance": 4500, "interest_rate": 22.99, "min_monthly_payment": 120 } ``` Debt types: `loan`, `credit_card`, `personal_loan`, `student_loan`, `medical_debt`, `auto_loan`, `line_of_credit`, `mortgage` Required: `name`, `type`, `balance`, `interest_rate`, `min_monthly_payment` ### Response (201) ```json { "id": 42, "name": "Chase Sapphire", "type": "credit_card", "balance": 4500.0, "interest_rate": 22.99, "min_monthly_payment": 120.0 } ``` ### GET /api/v1/debts/:id Same response shape as create. ### PATCH or PUT /api/v1/debts/:id Same request shape as create, but only the fields provided are changed. ### DELETE /api/v1/debts/:id Soft-deletes a debt account. ### Response ```json { "data": { "id": 42, "deleted": true } } ``` --- ## Budgets Budgets are scoped to the authenticated user (personal or guest key). A budget has a name, a total `budget_amount`, an optional date range, and a list of category `items`; each item can have `expenses` recorded against it. ### GET /api/v1/budget-categories Returns the standard list of expense categories. Use one of these when creating budget items or recording expenses. ### Response ```json { "data": [ "Housing", "Transportation", "Food & Dining", "Utilities", "Healthcare", "Entertainment", "Shopping", "Personal Care", "Education", "Debt Payments", "Savings", "Investments", "Other" ] } ``` --- ### GET /api/v1/budgets Lists all budgets belonging to the authenticated user. ### Response ```json { "data": [ { "id": 4, "user_id": 1, "name": "July 2026", "budget_amount": 2000.0, "budget_start_date": "2026-07-01", "budget_end_date": "2026-07-31", "items": [], "incomes": [] } ] } ``` --- ### POST /api/v1/budgets Creates a budget. `items` and `incomes` are both optional — omit them to create an empty budget. ### Request ```json { "name": "July 2026", "budget_amount": 2000.0, "budget_start_date": "2026-07-01", "budget_end_date": "2026-07-31", "items": [ { "name": "Rent", "category": "rent", "amount": 1500.0 }, { "name": "Groceries", "category": "groceries", "amount": 400.0 } ], "incomes": [ { "name": "Paycheck", "source": "Salary", "amount": 3000.0 } ] } ``` Required: `name`, `budget_amount` Optional: `budget_start_date`, `budget_end_date`, `items`, `incomes` ### Response (201) ```json { "id": 4, "user_id": 1, "name": "July 2026", "budget_amount": 2000.0, "budget_start_date": "2026-07-01", "budget_end_date": "2026-07-31", "items": [ { "id": 12, "budget_id": 4, "name": "Rent", "category": "rent", "amount": 1500.0, "amount_spent": 0.0, "frequency": null, "budget_goal_id": null } ], "incomes": [ { "id": 7, "budget_id": 4, "name": "Paycheck", "source": "Salary", "amount": 3000.0, "frequency": null } ] } ``` --- ### GET /api/v1/budgets/:id Returns a budget with its categories, recorded expenses, and income sources. 404 if it doesn't exist or doesn't belong to the authenticated user. --- ### PATCH or PUT /api/v1/budgets/:id Updates `name`, `budget_amount`, or dates. Same request/response shape as create. Providing `items` fully replaces the existing category list; providing `incomes` fully replaces the existing income list; omitting either leaves that list untouched. --- ### DELETE /api/v1/budgets/:id Soft-deletes a budget along with its categories and expenses. ### Response ```json { "data": { "id": 4, "deleted": true } } ``` --- ### POST /api/v1/budgets/:id/share-link Creates a shareable link to the budget. Anyone with the link can open it at the returned `share_url` — no login required to view it. ### Response (201) ```json { "id": 7, "budget_id": 4, "unique_link_id": "aB3dEfGhIjKlMnOp", "share_url": "https://wealth-tools.com/budgets/aB3dEfGhIjKlMnOp" } ``` --- ### POST /api/v1/budgets/:budget_id/items Adds a category to a budget. ### Request ```json { "name": "Eating out", "category": "eating out", "amount": 100.0, "frequency": "monthly" } ``` Required: `name`, `category`, `amount` Optional: `frequency` (`weekly`, `biweekly`, `semi-monthly`, `monthly`, `custom`), `budget_goal_id` ### Response (201) ```json { "id": 12, "budget_id": 4, "name": "Eating out", "category": "eating out", "amount": 100.0, "amount_spent": 0.0, "frequency": "monthly", "budget_goal_id": null } ``` --- ### PATCH or PUT /api/v1/budgets/:budget_id/items/:id Updates a category. Same request/response shape as create. --- ### DELETE /api/v1/budgets/:budget_id/items/:id Removes a category. Response: `{ "data": { "id": 12, "deleted": true } }` --- ### POST /api/v1/budgets/:budget_id/incomes Adds an income source to a budget. ### Request ```json { "name": "Paycheck", "source": "Salary", "amount": 3000.0, "frequency": "monthly" } ``` Required: `name`, `source`, `amount` Optional: `frequency` (`weekly`, `biweekly`, `semi-monthly`, `monthly`, `custom`) ### Response (201) ```json { "id": 7, "budget_id": 4, "name": "Paycheck", "source": "Salary", "amount": 3000.0, "frequency": "monthly" } ``` --- ### PATCH or PUT /api/v1/budgets/:budget_id/incomes/:id Updates an income source. Same request/response shape as create. --- ### DELETE /api/v1/budgets/:budget_id/incomes/:id Removes an income source. Response: `{ "data": { "id": 7, "deleted": true } }` --- ### POST /api/v1/budgets/:budget_id/items/:item_id/expenses Records an expense against a category. ### Request ```json { "description": "McDonald's", "amount": 20.0 } ``` Required: `description`, `amount` ### Response (201) ```json { "id": 87, "budget_item_id": 12, "description": "McDonald's", "amount": 20.0 } ``` --- ### PATCH or PUT /api/v1/expenses/:id Corrects a recorded expense's `description` or `amount`. Same response shape as create. --- ### DELETE /api/v1/expenses/:id Deletes a recorded expense. Response: `{ "data": { "id": 87, "deleted": true } }` --- ## Authentication Every endpoint requires `Authorization: Bearer YOUR_API_KEY`. There is no anonymous/keyless access to anything, including the calculators above. If you don't already have a key, get one first: ``` POST /api/v1/guest-key ``` No request body needed. Response: ```json { "api_key": "wt_AbCdEfGhIjKlMnOpQrStUvWxYz0123456789" } ``` Save it — reuse the same key on every subsequent call. A human can instead sign in and generate a personal key at https://wealth-tools.com/users/settings for a higher rate limit. Calling any other endpoint without a key returns HTTP 401 with an error message pointing back to `POST /api/v1/guest-key`. --- ## MCP Server (AI Assistant Connector) In addition to the REST API above, WealthTools exposes an MCP (Model Context Protocol) server so AI assistants like Claude Desktop and ChatGPT can act on a user's own WealthTools account directly in a conversation — running calculators, managing debt accounts (list, add, update, and remove the debts tracked by the Debt Payoff Planner), and managing budgets (create/edit budgets and categories, record and edit expenses in natural language, e.g. "I spent 20 bucks this week on eating out", manage income sources (add, update, and remove), and invite collaborators to a budget by email). - MCP endpoint: `POST https://wealth-tools.com/mcp` (JSON-RPC 2.0) - Human setup guide: https://wealth-tools.com/using-the-wealth-tools-mcp - Machine-readable manifest: https://wealth-tools.com/.well-known/agent.json Unlike the REST API above, the MCP endpoint is authenticated via OAuth 2.1 (not a static API key), scoped to a signed-in WealthTools user: 1. Resource discovery: `GET /.well-known/oauth-protected-resource` 2. Authorization server discovery: `GET /.well-known/oauth-authorization-server` 3. Dynamic client registration (RFC 7591): `POST /oauth/register` 4. Authorization (requires a WealthTools login in the browser): `GET /oauth/authorize` 5. Token exchange (PKCE, S256 only): `POST /oauth/token` 6. Calls to `/mcp` use `Authorization: Bearer ` with standard MCP methods (`initialize`, `tools/list`, `tools/call`) MCP clients (Claude Desktop, ChatGPT) perform this discovery and registration automatically once given the `/mcp` URL — no manual API key is involved. ### MCP-only tools Some MCP tools have no REST equivalent. Call these via the `tools/call` method with the tool's `name` and `arguments`. #### compare_mortgage_schedules Compares a baseline mortgage (no extra payments) against one or more named scenarios. Each scenario may override the baseline's `home_value`, `down_payment_percent`, `interest_rate`, and/or `term_years` (e.g. to compare a 15-year at a lower rate against the baseline's 30-year), add `extra_payments`, or both at once. A scenario's `extra_payments` can mix one-time lump sums and recurring extra payments (optionally bounded to a date range, e.g. an extra $250/month for only the first 5 years); entries landing in the same month are summed. Request: ```json { "home_value": 400000, "down_payment_percent": 20, "interest_rate": 6.25, "term_years": 30, "scenarios": [ { "name": "15-year at 5.8% + $100/month extra", "interest_rate": 5.8, "term_years": 15, "extra_payments": [ { "type": "recurring", "amount": 100, "every": 1, "unit": "months" } ] }, { "name": "30-year at baseline rate + $250/month extra for 5 years", "extra_payments": [ { "type": "recurring", "amount": 250, "every": 1, "unit": "months", "end_period": "2031-07" } ] }, { "name": "$10,000 lump sum every January", "extra_payments": [ { "type": "recurring", "amount": 10000, "every": 1, "unit": "years" } ] } ] } ``` Extra payment shapes: - One-time: `{ "type": "one_time", "amount": 5000, "period": "2028-03" }` - Recurring: `{ "type": "recurring", "amount": 100, "every": 1, "unit": "months" | "weeks" | "years", "start_period": "YYYY-MM", "end_period": "YYYY-MM" }` (`start_period`/`end_period` are optional and default to the loan's first/last payment) Response: ```json { "baseline": { "name": "Baseline (no extra payments)", "loan_amount": 320000.0, "interest_rate": 6.25, "term_years": 30, "monthly_payment": 1970.3, "total_interest_paid": 389302.84, "total_amount_paid": 709302.84, "payoff_date": "2056-07-23", "term_months": 360 }, "scenarios": [ { "name": "15-year at 5.8% + $100/month extra", "loan_amount": 320000.0, "interest_rate": 5.8, "term_years": 15, "monthly_payment": 2665.89, "total_interest_paid": 149892.81, "total_amount_paid": 469892.81, "payoff_date": "2040-09-23", "term_months": 170, "interest_saved_vs_baseline": 239410.03, "months_saved_vs_baseline": 190 }, { "name": "30-year at baseline rate + $250/month extra for 5 years", "loan_amount": 320000.0, "interest_rate": 6.25, "term_years": 30, "monthly_payment": 1970.3, "total_interest_paid": 328731.53, "total_amount_paid": 648731.53, "payoff_date": "2053-05-23", "term_months": 322, "interest_saved_vs_baseline": 60571.31, "months_saved_vs_baseline": 38 } ] } ``` The baseline never has `interest_saved_vs_baseline`/`months_saved_vs_baseline`; every scenario result does. --- ## Error Responses All endpoints return a consistent error shape on validation failure (HTTP 422): ```json { "errors": { "field_name": ["is required", "must be greater than 0"] } } ``` --- ## Rate Limiting - Guest key (from `POST /api/v1/guest-key`): 20 requests per hour - Personal key (from https://wealth-tools.com/users/settings, requires signing in): 1,000 requests per hour - Limits are per-key, not per-IP - Exceeding the limit returns HTTP 429; a guest key's error message suggests generating a personal key for a higher limit - Response headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`