{"openapi":"3.0.3","info":{"title":"Fi-Plan Public Calculators API","version":"1.0.0","description":"Anonymous, no-auth financial calculators: loan amortization/prepayments, refinance analysis, asset projection, and plan what-if simulation (plan_json)."},"servers":[{"url":"https://www.fi-plan.in","description":"Fi-Plan"}],"paths":{"/api/public/calc":{"post":{"summary":"Run an anonymous Fi-Plan calculator","description":"Executes one public calculator. Pass the tool name via the `tool` query parameter (body = the tool args), or POST `{ tool, args }`.","operationId":"runPublicCalculator","parameters":[{"name":"tool","in":"query","required":true,"schema":{"type":"string","enum":["simulate_plan","loan_amortization","loan_refinance","asset_projection"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/simulate_plan"},{"$ref":"#/components/schemas/loan_amortization"},{"$ref":"#/components/schemas/loan_refinance"},{"$ref":"#/components/schemas/asset_projection"}]}}}},"responses":{"200":{"description":"Successful calculation"},"400":{"description":"Invalid arguments"},"404":{"description":"Unknown or non-public tool"},"429":{"description":"Rate limited"}}}}},"components":{"schemas":{"simulate_plan":{"description":"Applies an ordered list of scenario patches to a DEEP COPY of the plan (never persisted) and returns the resulting snapshot plus applied_patches. Pass plan_id to load the plan server-side (preferred — never paste plan_json); plan_json is accepted for portability. Pass summary=true for the compact view; add milestones=true for long durations to get yearly points + totals instead of every month. Patches support add_income, add_expense, add_cashflow_change, add_loan, update_loan (loan_id plus any of title, principal_amount, interest_rate, start_month, end_month, deposit_to_bank, type, ref_id, prepayments), add_fdp (fdp: { start_month, end_month, s, e, i } with s + e + i = 100 — or the legacy { amount, interest_rate, tenure } fixed-deposit shape) and set_account_balance — nested ({\"op\":\"add_cashflow_change\",\"change\":{...}}) and flat ({cashflow_id,value,start_month,...}) forms are both accepted; the op is inferred from the fields.","type":"object","properties":{"plan_id":{"type":"string","description":"Load a saved plan by id (authenticated tier only)."},"plan_json":{"type":"object","additionalProperties":{},"description":"Inline plan object for anonymous use; bounded to 256 KB."},"patches":{"type":"array","items":{"type":"object","additionalProperties":{}},"description":"Ordered scenario patches (add_income, add_expense, add_cashflow_change, add_loan, update_loan, add_fdp, set_account_balance)."},"duration":{"type":"number","description":"Projection length in months (public tier caps this)."},"summary":{"type":"boolean","description":"Return the compact summary (monthly totals + balances) instead of the full snapshot."},"milestones":{"type":"boolean","description":"With summary, return yearly points and totals instead of every month."}},"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"loan_amortization":{"description":"Pure calculation of EMI and a month-by-month amortization schedule for a loan of amount at annual interest_rate over tenure months. Returns opening/closing balance, interest, principal and running totals per month. Pass optional prepayments to model extra principal payments beyond the EMI (each {start_month, amount, frequency: 'm'|'q'|'y'|null, step_pct?} — null frequency = one-time lump, step_pct = % the amount grows by each recurrence): the EMI stays constant, the loan shortens, and the result becomes { schedule, payoff_month, total_interest_paid, total_prepaid, interest_saved } instead of a plain array. NOTE: here start_month is loan-relative (1 = the loan's first EMI month); on a persisted loan the same fields are plan-absolute months.","type":"object","properties":{"amount":{"type":"number","description":"Loan principal in rupees (e.g. 1500000 for ₹15,00,000)."},"interest_rate":{"type":"number","description":"Annual interest rate in percent (e.g. 8.6)."},"tenure":{"type":"number","description":"Loan tenure in months (e.g. 240 for 20 years)."},"prepayments":{"type":"array","items":{"type":"object","properties":{"start_month":{"type":"integer","minimum":1,"description":"Loan-relative month of this payment (1 = the loan's first EMI month)."},"amount":{"type":"number","exclusiveMinimum":0,"description":"Prepayment amount in rupees."},"frequency":{"anyOf":[{"type":"string","enum":["m","q","y"]},{"type":"null"}],"description":"Recurrence: m = monthly, q = quarterly, y = yearly; null = one-time lump."},"step_pct":{"type":"number","minimum":0,"description":"Percent the prepayment amount grows by each recurrence (step-up)."},"step_frequency":{"anyOf":[{"type":"string","enum":["m","q","y"]},{"type":"null"}],"description":"How often step_pct applies (defaults to frequency)."},"desc":{"type":"string","description":"Optional label for the prepayment."}},"required":["start_month","amount"],"additionalProperties":false},"description":"Optional extra principal payments beyond the EMI: the EMI stays constant and the loan shortens."}},"required":["amount","interest_rate","tenure"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"loan_refinance":{"description":"Pure what-if: closes the loan at refinance_month (outstanding balance settled) and restarts it at new_rate over new_tenure months. Returns outstanding balance, old vs new EMI, remaining interest vs new total interest, interest_saved, net_savings (after optional foreclosure_charge) and breakeven_months (null when the new EMI is not lower). Read-only — to persist, update the old loan's end_month and add the new loan.","type":"object","properties":{"amount":{"type":"number","exclusiveMinimum":0,"description":"Outstanding loan principal at refinance_month, in rupees."},"interest_rate":{"type":"number","minimum":0,"description":"Current annual interest rate in percent."},"tenure":{"type":"integer","minimum":1,"description":"Total tenure of the existing loan in months."},"refinance_month":{"type":"integer","minimum":1,"description":"Loan-relative month the refinance happens (outstanding balance is settled)."},"new_rate":{"type":"number","minimum":0,"description":"Annual interest rate of the new loan in percent."},"new_tenure":{"type":"integer","minimum":1,"description":"Tenure of the new loan in months."},"foreclosure_charge":{"type":"number","minimum":0,"description":"Foreclosure/prepayment penalty in rupees (default 0)."}},"required":["amount","interest_rate","tenure","refinance_month","new_rate","new_tenure"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"asset_projection":{"description":"Pure calculator for one asset (no plan needed): monthly value, invested, growth, income and TDS over duration months. Pass asset parameters (principal, growth_rate, yield_rate, income_frequency, income_mode, maturity_month, sale_month, sip) — class presets are NOT applied automatically, so pass explicit rates. TDS on FD interest follows the stored rules for the assessment_year. Returns rows plus closing value and totals.","type":"object","properties":{"title":{"type":"string","description":"Display name for the asset (defaults to 'Asset')."},"asset_class":{"type":"string","enum":["fd","bond","savings","gold","ppf","equity","equity_foreign","mf","real_estate","vda"],"description":"Asset type; affects default tax treatment (default 'fd')."},"category":{"type":"string","enum":["s","e","i"],"description":"Bucket: s = savings, e = expenses, i = investments (default 'i')."},"principal":{"type":"number","minimum":0,"description":"Starting value/principal in rupees."},"purchase_month":{"type":"integer","minimum":1,"description":"Month the asset is acquired (default 1)."},"growth_rate":{"type":"number","minimum":0,"description":"Annual capital growth rate in percent."},"yield_rate":{"type":"number","minimum":0,"description":"Annual income/yield rate in percent (interest, dividend, rent)."},"income_frequency":{"type":"string","enum":["m","q","h","y"],"description":"Income payout frequency: m monthly, q quarterly, h half-yearly, y yearly."},"income_mode":{"type":"string","enum":["credit","reinvest"],"description":"Where income goes: credit (cash) or reinvest."},"compounding":{"type":"string","enum":["none","simple","monthly","quarterly","yearly"],"description":"Compounding mode for growth (default none)."},"maturity_month":{"type":"integer","minimum":1,"description":"Month the asset matures; value is released then."},"sale_month":{"type":"integer","minimum":1,"description":"Month the asset is sold."},"rent":{"type":"object","properties":{"monthly_rent":{"type":"number","exclusiveMinimum":0,"description":"Monthly rent in rupees."},"step_pct":{"type":"number","minimum":0,"description":"Annual rent escalation percent."},"expense_ratio":{"type":"number","minimum":0,"maximum":100,"description":"Share of rent consumed by expenses, percent."}},"required":["monthly_rent"],"additionalProperties":false,"description":"Real-estate rent settings."},"sip":{"type":"object","properties":{"amount":{"type":"number","exclusiveMinimum":0,"description":"Instalment amount in rupees."},"frequency":{"type":"string","enum":["m","q","y"],"description":"Instalment frequency."},"start_month":{"type":"integer","minimum":1,"description":"First instalment month."},"end_month":{"type":"integer","minimum":1,"description":"Last instalment month."},"step_pct":{"type":"number","minimum":0,"description":"Percent each instalment steps up by."}},"required":["amount","frequency","start_month"],"additionalProperties":false,"description":"Optional recurring SIP into the asset."},"duration":{"type":"integer","minimum":1,"description":"Projection length in months (default 120)."},"assessment_year":{"type":"string","description":"Assessment year for tax rules, e.g. '2025-26' (default: current)."}},"required":["principal","growth_rate"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}}}}