{
  "openapi": "3.1.0",
  "info": {
    "title": "PoliErgaleio Cyprus Calculators",
    "version": "5.0.0",
    "description": "Stateless Cyprus financial calculators (income tax, state pension, mortgage, capital gains, retirement, rent vs buy and more). No sign-in required. Read numbers from structuredContent; all amounts in EUR."
  },
  "servers": [
    {
      "url": "https://gpkpjfdlbsuyevfdsnbq.supabase.co/functions/v1/public-api"
    }
  ],
  "components": {
    "schemas": {
      "ToolResponse": {
        "type": "object",
        "properties": {
          "content": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string"
                },
                "text": {
                  "type": "string"
                }
              }
            }
          },
          "structuredContent": {
            "type": "object",
            "properties": {
              "assumptions": {
                "type": "array",
                "description": "Defaults and exclusions applied by the calculation. This does not verify where input facts came from.",
                "items": {
                  "type": "object",
                  "properties": {
                    "field": {
                      "type": "string"
                    },
                    "value": {},
                    "reason": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "field",
                    "reason"
                  ],
                  "additionalProperties": true
                }
              }
            },
            "additionalProperties": true
          },
          "series": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "requestId": {
            "type": "string"
          },
          "guestId": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ValidationError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Validation failure summary."
          },
          "fieldErrors": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Missing, invalid or conditionally required input facts."
          },
          "hint": {
            "type": "string",
            "description": "Actionable correction guidance."
          },
          "requestId": {
            "type": "string",
            "description": "Request correlation id, also returned in X-Request-Id."
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": true
      }
    }
  },
  "paths": {
    "/tools/calculate_cyprus_income_tax": {
      "post": {
        "operationId": "calculate_cyprus_income_tax",
        "summary": "Computes Cyprus personal income tax, GESY (National Health System) contributions, social insurance, and net (take-home) salary.",
        "description": "Estimate Cyprus income tax and take-home pay. Ask for gross annual salary; self-employed cases also need turnover and occupational category. Do not infer optional income, deductions or exemption eligibility.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "salaryIncome": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Gross annual salary in EUR."
                  },
                  "rentalIncome": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Annual rental income in EUR."
                  },
                  "hasRentalIncome": {
                    "type": "boolean",
                    "description": "Whether rental income applies."
                  },
                  "dividendIncome": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Annual dividend income in EUR."
                  },
                  "hasDividendIncome": {
                    "type": "boolean",
                    "description": "Whether dividend income applies."
                  },
                  "isDividendNonDomicile": {
                    "type": "boolean",
                    "description": "Non-dom status for dividends."
                  },
                  "employmentType": {
                    "type": "string",
                    "enum": [
                      "private",
                      "civil",
                      "self-employed"
                    ],
                    "description": "'private' for private sector (8.8% SI), 'civil' for civil service (4.45% SI), 'self-employed' for sole proprietor (16.6% SI on deemed/actual, 4% GESY). Required; the API does not assume a category."
                  },
                  "qualifiesForFirstEmployment": {
                    "type": "boolean"
                  },
                  "firstEmploymentDeduction": {
                    "type": "string",
                    "enum": [
                      "",
                      "20",
                      "50"
                    ]
                  },
                  "selfEmployedDetails": {
                    "type": "object",
                    "description": "Sole-proprietor schedule: net profit = turnover − expenses − capitalAllowances − lossBroughtForward (floor 0).",
                    "properties": {
                      "turnover": {
                        "type": "number",
                        "minimum": 0
                      },
                      "expenses": {
                        "type": "number",
                        "minimum": 0
                      },
                      "capitalAllowances": {
                        "type": "number",
                        "minimum": 0
                      },
                      "lossBroughtForward": {
                        "type": "number",
                        "minimum": 0
                      },
                      "occupationalCategory": {
                        "type": "string",
                        "minLength": 1,
                        "description": "MLSI occupational category driving weekly deemed earnings; obtain it from the user."
                      },
                      "useActualEarningsForSI": {
                        "type": "boolean",
                        "description": "Pay SI on actual profit when higher than deemed."
                      }
                    },
                    "additionalProperties": false
                  },
                  "exemptionType": {
                    "type": "string",
                    "enum": [
                      "none",
                      "article_8_21a",
                      "article_8_23a",
                      "article_8_21b_minds_in_cyprus"
                    ],
                    "description": "Minds in Cyprus Art. 8(21B), applied only when eligibility conditions are met."
                  },
                  "mindsEligibility": {
                    "type": "object",
                    "description": "Facts used to validate Minds in Cyprus Art. 8(21B). Omit or leave incomplete to receive no 8(21B) deduction.",
                    "properties": {
                      "cyprusStartDate": {
                        "type": "string",
                        "format": "date",
                        "description": "Date the Cyprus employment or business began."
                      },
                      "first12MonthsQualifyingIncome": {
                        "type": "number",
                        "minimum": 0,
                        "description": "Qualifying Cyprus remuneration or business profits in the first 12 months after starting."
                      },
                      "nonResidentForPriorSevenYears": {
                        "type": "boolean",
                        "description": "Not Cyprus tax resident throughout the seven years before starting."
                      },
                      "residentBeforePriorSevenYears": {
                        "type": "boolean",
                        "description": "Cyprus tax resident in a year before those seven years."
                      },
                      "recognizedUniversityDegree": {
                        "type": "boolean",
                        "description": "Holds a degree recognized by the Cyprus Council for the Recognition of Higher Education Qualifications."
                      },
                      "fullTimeForeignEmploymentMonthsPrior84": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 84,
                        "description": "Months of full-time foreign employment during the preceding 84 months."
                      },
                      "cyprusTaxResidentInClaimYear": {
                        "type": "boolean",
                        "description": "Cyprus tax resident in the claim year; not required for the commencement year."
                      }
                    },
                    "additionalProperties": false
                  },
                  "pensionIncome": {
                    "type": "object",
                    "properties": {
                      "cyprusPension": {
                        "type": "number",
                        "minimum": 0
                      },
                      "foreignPension": {
                        "type": "number",
                        "minimum": 0
                      },
                      "foreignPensionTaxMethod": {
                        "type": "string",
                        "enum": [
                          "flat_5_percent",
                          "progressive"
                        ]
                      }
                    },
                    "additionalProperties": false
                  },
                  "depositInterestIncome": {
                    "type": "number",
                    "minimum": 0
                  },
                  "cryptoTradingIncome": {
                    "type": "number",
                    "minimum": 0
                  },
                  "taxesPrepaid": {
                    "type": "object",
                    "properties": {
                      "payeWithheld": {
                        "type": "number",
                        "minimum": 0
                      },
                      "provisionalInstallments": {
                        "type": "number",
                        "minimum": 0
                      },
                      "sdcWithheld": {
                        "type": "number",
                        "minimum": 0
                      },
                      "gesyWithheld": {
                        "type": "number",
                        "minimum": 0
                      }
                    },
                    "additionalProperties": false
                  },
                  "propertyPrice": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Property price for wear-and-tear allowance."
                  },
                  "propertyYear": {
                    "type": "integer",
                    "description": "Year the property was acquired."
                  },
                  "interestPaid": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Interest paid on rental property."
                  },
                  "isNonDomicile": {
                    "type": "boolean",
                    "description": "Non-dom status for rental income."
                  },
                  "tradeUnionSubs": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "donations": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "innovativeInvestment": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "providentFund": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Total provident/PEPP fund contribution in EUR."
                  },
                  "legislationVersion": {
                    "type": "string",
                    "enum": [
                      "2025",
                      "2026"
                    ],
                    "description": "Tax/legislation year. Supported: 2025, 2026."
                  },
                  "maritalStatus": {
                    "type": "string",
                    "enum": [
                      "single",
                      "married",
                      "cohabiting"
                    ]
                  },
                  "numDependentChildren": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "spouseIncome": {
                    "type": "number",
                    "minimum": 0
                  },
                  "housingInterestPaid": {
                    "type": "number",
                    "minimum": 0
                  },
                  "rentPaidPrimary": {
                    "type": "number",
                    "minimum": 0
                  },
                  "energyEfficiencyExpense": {
                    "type": "number",
                    "minimum": 0
                  },
                  "evExpense": {
                    "type": "number",
                    "minimum": 0
                  },
                  "homeInsurancePremium": {
                    "type": "number",
                    "minimum": 0
                  }
                },
                "additionalProperties": false,
                "required": [
                  "salaryIncome",
                  "employmentType"
                ],
                "allOf": [
                  {
                    "if": {
                      "properties": {
                        "employmentType": {
                          "const": "self-employed"
                        }
                      },
                      "required": [
                        "employmentType"
                      ]
                    },
                    "then": {
                      "required": [
                        "selfEmployedDetails"
                      ],
                      "properties": {
                        "selfEmployedDetails": {
                          "required": [
                            "turnover",
                            "occupationalCategory"
                          ]
                        }
                      }
                    }
                  }
                ]
              },
              "example": {
                "salaryIncome": 45000,
                "legislationVersion": "2026",
                "employmentType": "private"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "On a gross income of €45,000, take-home (net salary after income tax, social insurance and GESY) is €35,885.63 (effective rate 20.25%)."
                    }
                  ],
                  "structuredContent": {
                    "grossIncome": 45000,
                    "netIncome": 45000,
                    "netSalary": 35885.63,
                    "chargeableIncome": 39847.5,
                    "incomeTax": 3961.88,
                    "socialInsurance": 3960,
                    "gesy": 1192.5,
                    "totalDeductions": 5152.5,
                    "availableDeductions": 3847.5,
                    "specialDefenseContribution": 0,
                    "mindsDeduction": 0,
                    "mindsEligibility": null,
                    "effectiveTaxRate": 20.25
                  },
                  "series": []
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/calculate_cyprus_state_pension": {
      "post": {
        "operationId": "calculate_cyprus_state_pension",
        "summary": "Estimates the Cyprus state (contributory) pension amount at retirement based on accumulated insurance units and contribution history.",
        "description": "Estimate Cyprus contributory state pension. Ask for retirement age and either current age, actual contribution years and total units, or a non-empty yearly contribution record. Never invent contribution history.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "quick",
                      "advanced"
                    ],
                    "description": "Calculation mode."
                  },
                  "currentAge": {
                    "type": "integer",
                    "minimum": 18,
                    "maximum": 70,
                    "description": "Current age (quick mode only)."
                  },
                  "retirementAge": {
                    "type": "integer",
                    "minimum": 63,
                    "maximum": 67,
                    "description": "Planned retirement age."
                  },
                  "yearsWorked": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 49,
                    "description": "Actual years with insurance contributions (quick mode); do not infer from age or employment duration."
                  },
                  "totalInsuranceUnits": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Actual accumulated Cyprus insurance units/points (quick mode); do not infer from salary or years worked."
                  },
                  "yearlyUnits": {
                    "type": [
                      "array",
                      "object"
                    ],
                    "description": "Advanced mode only. Insurance units earned per calendar year, e.g. [{\"year\":2003,\"units\":5.2}]. Units per year must be between 0 and the statutory maximum for that year (about 5.3-6.0; 6.0 for years after 2026). A legacy object map {\"2003\": 5.2} is also accepted. Years worked and total units are derived from this array, so yearsWorked/totalInsuranceUnits are ignored in advanced mode.",
                    "patternProperties": {
                      "^[0-9]{4}$": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 6
                      }
                    },
                    "additionalProperties": false,
                    "items": {
                      "type": "object",
                      "properties": {
                        "year": {
                          "type": "integer",
                          "minimum": 1981,
                          "description": "Calendar year of the contributions."
                        },
                        "units": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 6,
                          "description": "Insurance units earned that year."
                        }
                      },
                      "additionalProperties": false,
                      "required": [
                        "year",
                        "units"
                      ]
                    },
                    "minItems": 1
                  },
                  "dependents": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 10,
                    "description": "Number of dependents (spouse/children); raises the basic pension multiplier."
                  }
                },
                "required": [
                  "mode",
                  "retirementAge"
                ],
                "allOf": [
                  {
                    "if": {
                      "properties": {
                        "mode": {
                          "const": "quick"
                        }
                      },
                      "required": [
                        "mode"
                      ]
                    },
                    "then": {
                      "required": [
                        "currentAge",
                        "yearsWorked",
                        "totalInsuranceUnits"
                      ]
                    }
                  },
                  {
                    "if": {
                      "properties": {
                        "mode": {
                          "const": "advanced"
                        }
                      },
                      "required": [
                        "mode"
                      ]
                    },
                    "then": {
                      "required": [
                        "yearlyUnits"
                      ]
                    }
                  }
                ]
              },
              "example": {
                "mode": "quick",
                "currentAge": 45,
                "retirementAge": 65,
                "yearsWorked": 22,
                "totalInsuranceUnits": 132,
                "dependents": 0
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Estimated Cyprus state pension: €1,908.11/month gross, €1,824.50/month net."
                    }
                  ],
                  "structuredContent": {
                    "estimatedMonthlyPension": 1908.11,
                    "estimatedAnnualPension": 24805.44,
                    "basicPensionComponent": 5856.84,
                    "earningsRelatedComponent": 18948.6,
                    "minimumPensionApplied": false,
                    "qualifiesForPension": true,
                    "monthlyNet": 1824.5,
                    "weeklyGross": 477.03,
                    "ghsDeduction": 657.34,
                    "incomeTax": 429.62,
                    "yearsWorked": 22,
                    "totalUnits": 132
                  },
                  "series": [
                    {
                      "chartId": "unitsByYear",
                      "title": "Insurance units by year",
                      "xKey": "year",
                      "yKeys": [
                        "units"
                      ],
                      "points": [
                        {
                          "year": 2003,
                          "units": 5.2
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/run_retirement_stress_test": {
      "post": {
        "operationId": "run_retirement_stress_test",
        "summary": "Runs a deterministic projection plus Monte Carlo simulation of a retirement savings plan to estimate the probability of not running out of money.",
        "description": "Project retirement savings sustainability. Ask for current and retirement ages, savings, monthly contributions and drawdown. Disclose modelling defaults; omitted state pension income is excluded.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "currentAge": {
                    "type": "integer",
                    "minimum": 18,
                    "description": "Age today."
                  },
                  "retirementAge": {
                    "type": "integer",
                    "minimum": 18,
                    "description": "Planned retirement age."
                  },
                  "endAge": {
                    "type": "integer",
                    "default": 90,
                    "description": "Planning horizon age (default 90)."
                  },
                  "currentSavings": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Current investable savings balance in EUR."
                  },
                  "monthlyContribution": {
                    "type": "number",
                    "description": "Monthly contribution until retirement in EUR."
                  },
                  "expectedAnnualReturn": {
                    "type": "number",
                    "default": 6,
                    "description": "Annual percentage value (e.g. 2.5 for 2.5%). Supply the actual rate unless the user accepts a stated modelling default."
                  },
                  "expectedAnnualReturnRetirement": {
                    "type": "number",
                    "default": 4,
                    "description": "Annual percentage value (e.g. 2.5 for 2.5%). Supply the actual rate unless the user accepts a stated modelling default."
                  },
                  "monthlyDrawdown": {
                    "type": "number",
                    "description": "Planned monthly withdrawal in retirement in EUR."
                  },
                  "inflationRate": {
                    "type": "number",
                    "default": 2.5,
                    "description": "Annual percentage value (e.g. 2.5 for 2.5%). Supply the actual rate unless the user accepts a stated modelling default."
                  },
                  "statePension": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Expected monthly state pension in EUR."
                  },
                  "simulations": {
                    "type": "integer",
                    "minimum": 100,
                    "maximum": 5000,
                    "default": 1000,
                    "description": "Monte Carlo runs (default 1000)."
                  },
                  "seed": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 4294967295,
                    "description": "Optional unsigned 32-bit seed for repeatable runs with identical inputs and implementation versions. Omit to keep the run stochastic."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "currentAge",
                  "retirementAge",
                  "currentSavings",
                  "monthlyContribution",
                  "monthlyDrawdown"
                ]
              },
              "example": {
                "currentAge": 40,
                "retirementAge": 65,
                "endAge": 90,
                "currentSavings": 80000,
                "monthlyContribution": 500,
                "expectedAnnualReturn": 6,
                "expectedAnnualReturnRetirement": 4,
                "monthlyDrawdown": 2000,
                "inflationRate": 2.5,
                "statePension": 900,
                "seed": 20261009
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "This plan has an 87% probability of lasting to age 90 without depleting savings."
                    }
                  ],
                  "structuredContent": {
                    "successProbability": 87.4,
                    "medianDepletionAge": null,
                    "averageDepletionAge": null,
                    "deterministicFinalBalance": 142300.5,
                    "worstCase10thPercentileBalance": -18500
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/calculate_cyprus_unemployment_benefit": {
      "post": {
        "operationId": "calculate_cyprus_unemployment_benefit",
        "summary": "Estimates the Cyprus unemployment benefit amount and separately assesses entitlement when qualifying facts are supplied.",
        "description": "Estimate Cyprus unemployment benefit. Ask for application date, relevant annual insurable earnings, dependent spouse status and dependent child count. Do not infer household status.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "applicationDate": {
                    "type": "string",
                    "format": "date",
                    "description": "Actual claim date as YYYY-MM-DD."
                  },
                  "annualGrossEarnings": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Actual gross insurable earnings in EUR for the contribution year selected by applicationDate."
                  },
                  "dependentSpouse": {
                    "type": "boolean",
                    "description": "Whether the claimant has a dependent spouse not in paid work; ask if unknown."
                  },
                  "dependentChildren": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Actual number of dependent children or other dependants; ask if unknown (benefit calculation caps at 3)."
                  },
                  "actualBasicInsurancePoints": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Actual paid basic insurance points accumulated by claim date; 0.5 required for entitlement."
                  },
                  "weeksSinceFirstInsurance": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Weeks elapsed since first insurance; at least 26 required."
                  },
                  "relevantYearInsurancePoints": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Actual plus assimilated insurance points in the relevant contribution year; at least 0.39 required."
                  },
                  "registeredUnemployed": {
                    "type": "boolean",
                    "description": "Whether registered unemployed with the competent offices."
                  },
                  "capableAndAvailableForWork": {
                    "type": "boolean",
                    "description": "Whether capable of and available for work during the claim."
                  },
                  "isEmployee": {
                    "type": "boolean",
                    "description": "Whether the claimant was insured as an employee rather than self-employed."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "applicationDate",
                  "annualGrossEarnings",
                  "dependentSpouse",
                  "dependentChildren"
                ]
              },
              "example": {
                "applicationDate": "2026-01-15",
                "annualGrossEarnings": 32240,
                "dependentSpouse": true,
                "dependentChildren": 2
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Estimated unemployment benefit amount: €270.10/week for up to 26 weeks. Entitlement: undetermined; confirm qualifying insurance history, unemployment registration and availability for work."
                    }
                  ],
                  "structuredContent": {
                    "weeklyBenefit": 270.1,
                    "monthlyBenefit": 1170.45,
                    "maxEntitlementWeeks": 26,
                    "dependentSupplement": 48.38,
                    "earningsRelatedSupplement": 100.79,
                    "eligibilityStatus": "undetermined",
                    "eligible": null,
                    "missingEligibilityFacts": [
                      "actualBasicInsurancePoints",
                      "weeksSinceFirstInsurance",
                      "relevantYearInsurancePoints",
                      "registeredUnemployed",
                      "capableAndAvailableForWork",
                      "isEmployee"
                    ],
                    "missingEligibilityQuestions": [
                      "How many basic insurance points have you actually paid by the claim date?",
                      "How many weeks have passed since your first insurance?",
                      "How many actual plus assimilated insurance points do you have in the relevant contribution year?",
                      "Are you registered as unemployed with the competent offices?",
                      "Are you capable of and available for work during the claim?",
                      "Were you insured as an employee rather than as self-employed?"
                    ],
                    "failedEligibilityConditions": [],
                    "relevantContributionYear": 2024
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/get_pension_reference_data": {
      "post": {
        "operationId": "get_pension_reference_data",
        "summary": "Returns official Cyprus Social Insurance reference tables for a given year.",
        "description": "Retrieve Cyprus state-pension reference rates and rules. Use for general pension information; this does not estimate a person's pension.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "year": {
                    "type": "integer",
                    "minimum": 1981,
                    "description": "Reference year."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "year"
                ]
              },
              "example": {
                "year": 2026
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "2026 Cyprus Social Insurance reference: weekly BIE €220.76, annual ceiling €68,904."
                    }
                  ],
                  "structuredContent": {
                    "weeklyBasicInsurableEarnings": 220.76,
                    "annualBasicInsurableEarnings": 11480,
                    "annualMaxInsurableEarnings": 68904,
                    "maxUnitsPerYear": 6,
                    "statutoryPensionAge": 65,
                    "minimumContributionYears": 15
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/parse_pension_statement": {
      "post": {
        "operationId": "parse_pension_statement",
        "summary": "Extracts structured contribution history from pasted Cyprus Social Insurance Services pension statement text.",
        "description": "Extract contribution years and units from pasted pension statement text. Use only the supplied document; report unreadable or missing records and never fill gaps.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Pasted statement text."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "text"
                ]
              },
              "example": {
                "text": "Year 2020 units 4.5\nYear 2021 units 5.2\n"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Parsed 2 years of contributions totaling 9.7 insurance units."
                    }
                  ],
                  "structuredContent": {
                    "contributionYears": [
                      {
                        "year": 2020,
                        "units": 4.5
                      },
                      {
                        "year": 2021,
                        "units": 5.2
                      }
                    ],
                    "totalUnits": 9.7,
                    "totalContributionYears": 2,
                    "parseConfidence": 0.8
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/calculate_cyprus_capital_gains": {
      "post": {
        "operationId": "calculate_cyprus_capital_gains",
        "summary": "Calculates Cyprus Capital Gains Tax on an immovable property disposal, including CPI indexation of the acquisition cost, lifetime first-disposal exemptions, the 20% CGT rate and the 0.4% property transfer fee.",
        "description": "Estimate Cyprus capital gains tax on an immovable-property sale. Ask for actual acquisition and sale prices, acquisition year and property type. Do not infer lifetime exemption eligibility.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "acquisitionPrice": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "description": "Purchase price in the original currency."
                  },
                  "currency": {
                    "type": "string",
                    "enum": [
                      "EUR",
                      "CYP"
                    ],
                    "default": "EUR",
                    "description": "EUR (default) or CYP for pre-2008 purchases (converted at 0.585274)."
                  },
                  "acquisitionYear": {
                    "type": "integer",
                    "minimum": 1960,
                    "description": "Calendar year the property was acquired."
                  },
                  "salePrice": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "agentFees": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Estate agent / legal fees deducted from the sale price, EUR."
                  },
                  "propertyType": {
                    "type": "string",
                    "enum": [
                      "plot",
                      "house",
                      "agricultural",
                      "other"
                    ],
                    "description": "Drives the lifetime first-disposal exemption: plot €17,086, house €85,430, agricultural €25,629, other €0."
                  },
                  "isFirstDisposal": {
                    "type": "boolean",
                    "description": "Whether the lifetime first-disposal exemption is being claimed. Omission means no exemption is claimed."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "acquisitionPrice",
                  "acquisitionYear",
                  "salePrice",
                  "propertyType"
                ]
              },
              "example": {
                "acquisitionPrice": 120000,
                "currency": "EUR",
                "acquisitionYear": 2010,
                "salePrice": 320000,
                "agentFees": 8000,
                "propertyType": "house",
                "isFirstDisposal": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Capital gains tax due is €16,002.37 on a taxable gain of €80,011.86 (CPI-adjusted cost €146,558.14). Total including the property transfer fee: €17,282.37."
                    }
                  ],
                  "structuredContent": {
                    "acquisitionPriceEUR": 120000,
                    "currentValuation": 146558.14,
                    "netSalePrice": 312000,
                    "taxExemption": 85430,
                    "taxableGain": 80011.86,
                    "capitalGainsTax": 16002.37,
                    "propertyTransferFee": 1280,
                    "totalTaxDue": 17282.37,
                    "netProceeds": 294717.63
                  },
                  "series": [
                    {
                      "chartId": "cpiAdjustments",
                      "title": "CPI indexation by year",
                      "xKey": "year",
                      "yKeys": [
                        "cpi_rate"
                      ],
                      "points": [
                        {
                          "year": 2010,
                          "cpi_rate": 2.4
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/simulate_mortgage": {
      "post": {
        "operationId": "simulate_mortgage",
        "summary": "Calculate mortgage payments, amortization and rate scenarios from actual loan terms.",
        "description": "Calculate mortgage payments, amortization and rate scenarios. Ask for principal, term, fixed-period length and each applicable rate. For document checklists or general mortgage information, do not call this calculator; answer or research directly without narrating tool selection.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mortgageAmount": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "mortgageType": {
                    "type": "string",
                    "enum": [
                      "capital_and_interest",
                      "interest_only"
                    ],
                    "description": "Repayment structure. Defaults to capital_and_interest.",
                    "default": "capital_and_interest"
                  },
                  "loanPeriodYears": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 40,
                    "description": "Loan term in years."
                  },
                  "fixedPeriodYears": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Actual number of years at the fixed rate before variable pricing (0 means fully variable); ask if unknown."
                  },
                  "fixedRate": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 25,
                    "description": "Actual all-in annual fixed rate in percent, required when a fixed period applies."
                  },
                  "variableBaseRate": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 25,
                    "description": "Actual annual reference rate (such as ECB or Euribor) in percent, for the variable phase."
                  },
                  "bankMargin": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 25,
                    "description": "Actual bank margin in annual percentage points added to the variable base rate; do not split an all-in rate without confirmation."
                  },
                  "monthlyOverpayment": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Extra amount paid each month, EUR."
                  },
                  "overpaymentPeriodType": {
                    "type": "string",
                    "enum": [
                      "full",
                      "first",
                      "last"
                    ],
                    "description": "When overpayments are made across the term."
                  },
                  "overpaymentYearsCount": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Number of years overpayments run when period type is first/last."
                  },
                  "upfrontFees": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "feesAddedToLoan": {
                    "type": "boolean",
                    "description": "Whether upfront fees are capitalised into the loan."
                  },
                  "ercPercentage": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Early repayment charge, percent of the balance."
                  },
                  "ercPeriodYears": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Years the early repayment charge applies."
                  },
                  "closureFee": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "lumpSumOverpayments": {
                    "type": "array",
                    "description": "One-off overpayments.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "month": {
                          "type": "integer",
                          "minimum": 1,
                          "description": "Month number from the start of the loan."
                        },
                        "amount": {
                          "type": "number",
                          "minimum": 0,
                          "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                        }
                      }
                    }
                  }
                },
                "additionalProperties": false,
                "required": [
                  "mortgageAmount",
                  "loanPeriodYears",
                  "fixedPeriodYears"
                ]
              },
              "example": {
                "mortgageAmount": 10000,
                "mortgageType": "interest_only",
                "loanPeriodYears": 5,
                "fixedPeriodYears": 5,
                "fixedRate": 12,
                "monthlyOverpayment": 0,
                "upfrontFees": 0,
                "feesAddedToLoan": false,
                "ercPercentage": 2,
                "ercPeriodYears": 4,
                "closureFee": 50
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Monthly payment €100 (minimum €100). Total interest over the life of the loan: €6,000; €10,000 principal remains due at maturity after 5.0 years."
                    }
                  ],
                  "structuredContent": {
                    "minRequiredPayment": 100,
                    "totalMonthlyPayment": 100,
                    "totalInterestPaid": 6000,
                    "sumOfAllPayments": 6000,
                    "balloonDue": 10000,
                    "closureCashRequired": 10050,
                    "earlyRepaymentBalanceYear3": 10000,
                    "earlyRepaymentChargeYear3": 200,
                    "earlyRepaymentClosureCashYear3": 10250,
                    "actualRepaymentMonths": 60,
                    "actualRepaymentYears": 5,
                    "avgAnnualCapitalPayment": 0,
                    "avgAnnualInterestPayment": 1200,
                    "totalInterestByScenario": {
                      "default": 6000,
                      "best": 6000,
                      "worst": 6000,
                      "varied": 6000
                    }
                  },
                  "series": [
                    {
                      "chartId": "balanceByYear",
                      "title": "Outstanding balance by year",
                      "xKey": "year",
                      "yKeys": [
                        "balance",
                        "interest",
                        "capital"
                      ],
                      "points": [
                        {
                          "year": 1,
                          "interest": 1200,
                          "capital": 0,
                          "balance": 10000
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/calculate_stock_options": {
      "post": {
        "operationId": "calculate_stock_options",
        "summary": "Compares the Cyprus tax on an employee stock option exercise under the 2025 benefit-in-kind rules (progressive income tax) and the 2026 approved-scheme rules (flat 8% within caps), including the 2x salary annual cap and the €1m rolling 10-year lifetime cap.",
        "description": "Compare Cyprus tax on employee share-option exercise. Before any personalized option gain, tax or savings figures, ask for actual salary, share count and prices, and user-confirmed scheme approval. Never infer approval or calculate before confirmation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "annualGrossSalary": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Gross annual salary in EUR (sets the marginal band and the 2x annual cap)."
                  },
                  "numberOfShares": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "description": "Number of options being exercised."
                  },
                  "exercisePrice": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Strike price per share, EUR."
                  },
                  "marketPrice": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "description": "Market price per share at exercise, EUR."
                  },
                  "prior10YearOptionIncome": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Option income already used against the €1m rolling 10-year cap, EUR."
                  },
                  "isApprovedScheme": {
                    "type": "boolean",
                    "description": "Whether the plan has approved-scheme status under 2026 rules; ask the user and use only their explicit confirmation. Never infer or assume this value."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "annualGrossSalary",
                  "numberOfShares",
                  "exercisePrice",
                  "marketPrice",
                  "isApprovedScheme"
                ]
              },
              "example": {
                "annualGrossSalary": 60000,
                "numberOfShares": 5000,
                "exercisePrice": 2,
                "marketPrice": 12,
                "prior10YearOptionIncome": 0,
                "isApprovedScheme": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Exercise gain €50,000.00. Tax under 2025 rules €17,500.00; under the 2026 approved-scheme rules €4,000.00 (saving €13,500.00)."
                    }
                  ],
                  "structuredContent": {
                    "totalGain": 50000,
                    "gainPerShare": 10,
                    "tax2025": {
                      "taxOnGain": 17500,
                      "totalTaxableIncome": 110000,
                      "effectiveRate": 35
                    },
                    "tax2026": {
                      "annualCap": 120000,
                      "lifetimeRemaining": 1000000,
                      "eligibleForFlatRate": 50000,
                      "excessGain": 0,
                      "flatRateTax": 4000,
                      "excessTax": 0,
                      "totalTax": 4000,
                      "effectiveRate": 8,
                      "capWarnings": []
                    },
                    "taxSavings": 13500,
                    "savingsPercentage": 77.14
                  },
                  "series": []
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/compare_rent_vs_buy": {
      "post": {
        "operationId": "compare_rent_vs_buy",
        "summary": "Compares buying a home against renting and investing the difference over a multi-year horizon, modelling the mortgage, purchase and selling costs, maintenance, rent inflation and investment returns, and reporting the breakeven year.",
        "description": "Compare buying a home with renting in Cyprus. Use current-scenario facts; confirm before reusing values from another chat. If a deposit such as '20' has no unit, ask EUR or percent before interpreting or calculating. Disclose material assumptions and excluded costs.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "propertyPrice": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "downPayment": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Deposit amount. If the user gives no unit, ask whether it is EUR or a percentage before interpreting or calculating."
                  },
                  "downPaymentIsPercentage": {
                    "type": "boolean",
                    "description": "True only when the user explicitly confirms the deposit is a percentage; false only when they explicitly confirm it is EUR. Ask if unclear; never infer."
                  },
                  "mortgageInterestRate": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 25,
                    "description": "Annual percentage value (e.g. 2.5 for 2.5%). Supply the actual rate unless the user accepts a stated modelling default."
                  },
                  "mortgageTermYears": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 40,
                    "description": "Mortgage term in years."
                  },
                  "legalFees": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "transferFees": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "agentCommission": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "stampDuty": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "propertyTaxYearly": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Annual property tax, EUR."
                  },
                  "localAuthorityTax": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Annual local authority tax, EUR."
                  },
                  "homeInsurance": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Annual home insurance, EUR."
                  },
                  "maintenancePercentage": {
                    "type": "number",
                    "minimum": 0,
                    "default": 1,
                    "description": "Annual maintenance as a percent of property value (model default 1%)."
                  },
                  "maintenanceFixed": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Annual maintenance in EUR when not using the percentage."
                  },
                  "useMaintenancePercentage": {
                    "type": "boolean",
                    "default": true,
                    "description": "Use the percentage instead of the fixed maintenance figure (default true)."
                  },
                  "fittingsFurniture": {
                    "type": "number",
                    "minimum": 0,
                    "description": "One-off furnishing cost when buying, EUR."
                  },
                  "monthlyRent": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "description": "Current monthly rent, EUR."
                  },
                  "securityDepositMonths": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Deposit expressed in months of rent."
                  },
                  "agencyFees": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "rentFurniture": {
                    "type": "number",
                    "minimum": 0,
                    "description": "One-off furnishing cost when renting, EUR."
                  },
                  "commonAreaExpenses": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Monthly communal charges when renting, EUR."
                  },
                  "rentYearlyIncrease": {
                    "type": "number",
                    "minimum": 0,
                    "default": 2,
                    "description": "Assumed annual rent increase, percent (default 2)."
                  },
                  "investmentReturnRate": {
                    "type": "number",
                    "default": 5,
                    "description": "Assumed annual investment return, percent (default 5)."
                  },
                  "propertyAppreciationRate": {
                    "type": "number",
                    "default": 3,
                    "description": "Assumed annual property appreciation, percent (default 3)."
                  },
                  "generalInflationRate": {
                    "type": "number",
                    "default": 2,
                    "description": "Assumed annual inflation, percent (default 2)."
                  },
                  "salesCommissionRate": {
                    "type": "number",
                    "minimum": 0,
                    "default": 5,
                    "description": "Assumed selling commission on exit, percent (default 5%)."
                  },
                  "transferTaxOnSale": {
                    "type": "number",
                    "minimum": 0,
                    "default": 0,
                    "description": "Assumed transfer tax on exit, percent (default 0%)."
                  },
                  "analysisPeriodYears": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 50,
                    "default": 30,
                    "description": "Comparison horizon in years (default 30)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "propertyPrice",
                  "monthlyRent",
                  "downPayment",
                  "downPaymentIsPercentage",
                  "mortgageInterestRate",
                  "mortgageTermYears"
                ]
              },
              "example": {
                "propertyPrice": 300000,
                "downPayment": 20,
                "downPaymentIsPercentage": true,
                "mortgageInterestRate": 4,
                "mortgageTermYears": 25,
                "monthlyRent": 1200,
                "rentYearlyIncrease": 2,
                "investmentReturnRate": 5,
                "propertyAppreciationRate": 3,
                "analysisPeriodYears": 30
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Buying overtakes renting in year 9. Monthly mortgage payment €1,266.71; net wealth at the end of the horizon is €560,120.00 if you buy versus €312,480.00 if you rent and invest the difference."
                    }
                  ],
                  "structuredContent": {
                    "breakevenYear": 9,
                    "monthlyMortgagePayment": 1266.71,
                    "buyInitialCash": 70500,
                    "rentInitialCash": 5600,
                    "totalCostBuy": 612000,
                    "totalCostRent": 585000,
                    "buyNetWealthFinal": 560120,
                    "rentNetWealthFinal": 312480,
                    "opportunityCostGain": 247580
                  },
                  "series": [
                    {
                      "chartId": "netWealthByYear",
                      "title": "Net wealth: buy versus rent",
                      "xKey": "year",
                      "yKeys": [
                        "buyNetWealth",
                        "rentNetWealth"
                      ],
                      "points": [
                        {
                          "year": 1,
                          "buyNetWealth": 62000,
                          "rentNetWealth": 70000
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/calculate_ev_savings": {
      "post": {
        "operationId": "calculate_ev_savings",
        "summary": "Compares the annual running cost of an electric car against a petrol/diesel car in Cyprus, splitting charging between spare solar production, home grid electricity and public chargers, and reporting yearly savings and payback on the extra purchase cost.",
        "description": "Compare electric and petrol/diesel running costs. Ask for actual distance, consumption, fuel price and relevant charging shares and tariffs; ask for spare solar production when solar charging is selected.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "annualDistance": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "description": "Kilometres driven per year."
                  },
                  "iceConsumption": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Petrol/diesel consumption in litres per 100 km."
                  },
                  "fuelPrice": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Fuel price in EUR per litre."
                  },
                  "evConsumption": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "description": "EV consumption in Wh per km (e.g. 170)."
                  },
                  "chargingEfficiency": {
                    "type": "number",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 92,
                    "description": "Wall-to-battery charging efficiency, percent (default 92)."
                  },
                  "spareSolar": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Spare solar production available for charging, kWh per year."
                  },
                  "gridElectricityPrice": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Home electricity price in EUR per kWh."
                  },
                  "solarDirectShare": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Share of home charging covered directly by solar, percent."
                  },
                  "homeGridShare": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Share of home charging drawn from the grid, percent."
                  },
                  "publicChargingPrice": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Public charging price in EUR per kWh."
                  },
                  "extraEvCost": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Extra purchase cost of the EV versus the petrol/diesel alternative, EUR."
                  },
                  "iceService": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Annual servicing cost of the petrol/diesel car, EUR."
                  },
                  "iceOilChange": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "iceInsurance": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "iceRoadTax": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "iceOther": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "evInsurance": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "evRoadTax": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "evOther": {
                    "type": "number",
                    "minimum": 0,
                    "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                  },
                  "projectionYears": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 30,
                    "default": 10,
                    "description": "Horizon of the cumulative savings series (default 10)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "annualDistance",
                  "iceConsumption",
                  "fuelPrice",
                  "evConsumption"
                ],
                "allOf": [
                  {
                    "if": {
                      "properties": {
                        "homeGridShare": {
                          "exclusiveMinimum": 0
                        }
                      },
                      "required": [
                        "homeGridShare"
                      ]
                    },
                    "then": {
                      "required": [
                        "gridElectricityPrice"
                      ]
                    }
                  },
                  {
                    "if": {
                      "properties": {
                        "solarDirectShare": {
                          "exclusiveMinimum": 0
                        }
                      },
                      "required": [
                        "solarDirectShare"
                      ]
                    },
                    "then": {
                      "required": [
                        "spareSolar"
                      ]
                    }
                  }
                ]
              },
              "example": {
                "annualDistance": 15000,
                "iceConsumption": 7.5,
                "fuelPrice": 1.45,
                "evConsumption": 170,
                "chargingEfficiency": 92,
                "spareSolar": 2000,
                "gridElectricityPrice": 0.29,
                "solarDirectShare": 60,
                "homeGridShare": 40,
                "publicChargingPrice": 0.45,
                "extraEvCost": 6000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Running an EV costs €321.52/year versus €1,631.25/year for the petrol/diesel car — €1,309.73 saved per year, paying back the extra purchase cost in about 4.6 years."
                    }
                  ],
                  "structuredContent": {
                    "iceFuelCost": 1631.25,
                    "iceTotalAnnualCost": 1631.25,
                    "evEnergyAtWall": 2772,
                    "solarDirectEnergy": 1663,
                    "homeGridEnergy": 1109,
                    "publicChargingEnergy": 0,
                    "totalElectricityCost": 321.52,
                    "evTotalAnnualCost": 321.52,
                    "yearlySavings": 1309.73,
                    "paybackYears": 4.6
                  },
                  "series": [
                    {
                      "chartId": "cumulativeSavings",
                      "title": "Cumulative savings versus extra purchase cost",
                      "xKey": "year",
                      "yKeys": [
                        "cumulativeSavings"
                      ],
                      "points": [
                        {
                          "year": 1,
                          "cumulativeSavings": -4690.27
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/compare_investment_vehicles": {
      "post": {
        "operationId": "compare_investment_vehicles",
        "summary": "Compares a taxable investment (option 1) against a tax-deductible vehicle such as a provident fund or life-insurance savings plan (option 2), matching the true out-of-pocket cost of both and applying entry/exit fees, AUM fees, commission and exit tax.",
        "description": "Compare a taxable investment with a tax-deductible vehicle. Ask for annual contribution, tax-relief rate and option 2 management fee. Identify forecast returns and optional defaults as assumptions.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "netInvestment": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "description": "Annual GROSS contribution into option 2, EUR. Option 1 receives the equivalent out-of-pocket amount."
                  },
                  "taxDeductionRate": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "description": "User's marginal tax relief on option 2 contributions, percent."
                  },
                  "maxYears": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 60,
                    "default": 30,
                    "description": "Horizon in years (default 30)."
                  },
                  "opt1EntryFee": {
                    "type": "number",
                    "minimum": 0,
                    "description": "One-off entry fee on option 1, EUR."
                  },
                  "opt1ExitFee": {
                    "type": "number",
                    "minimum": 0,
                    "description": "One-off exit fee on option 1, EUR."
                  },
                  "opt1AnnualReturn": {
                    "type": "number",
                    "default": 5,
                    "description": "Annual percentage value (e.g. 2.5 for 2.5%). Supply the actual rate unless the user accepts a stated modelling default."
                  },
                  "opt1ExitTax": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Tax on option 1 gains at exit, percent."
                  },
                  "opt1MonthlyFee": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Fixed monthly fee on option 1, EUR."
                  },
                  "opt2AnnualReturn": {
                    "type": "number",
                    "default": 5,
                    "description": "Annual percentage value (e.g. 2.5 for 2.5%). Supply the actual rate unless the user accepts a stated modelling default."
                  },
                  "opt2AumFee": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Annual management fee on option 2, percent."
                  },
                  "opt2AdditionalFee": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Additional annual fee on option 2, percent."
                  },
                  "opt2MonthlyFee": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Fixed monthly fee on option 2, EUR."
                  },
                  "opt2ExitTax": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Tax on option 2 at exit, percent."
                  },
                  "opt2Commission": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Percent of the FIRST year's contributions taken as commission."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "netInvestment",
                  "taxDeductionRate",
                  "opt2AumFee"
                ]
              },
              "example": {
                "netInvestment": 5000,
                "taxDeductionRate": 25,
                "maxYears": 30,
                "opt1AnnualReturn": 5,
                "opt2AnnualReturn": 5,
                "opt2AumFee": 1.2,
                "opt2AdditionalFee": 0.092,
                "opt2MonthlyFee": 4,
                "opt2ExitTax": 5,
                "opt2Commission": 100
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "After the full horizon the taxable investment is ahead by €12,430.00 (€248,900.00 versus €236,470.00 net of exit tax and fees). The taxable option overtakes in year 12."
                    }
                  ],
                  "structuredContent": {
                    "crossoverYear": 12,
                    "option1AnnualContribution": 3750,
                    "option2AnnualContribution": 5000,
                    "option1Final": 248900,
                    "option2Final": 236470,
                    "winner": "option1",
                    "advantageAtHorizon": 12430
                  },
                  "series": [
                    {
                      "chartId": "netValueByYear",
                      "title": "Net value after exit tax by year",
                      "xKey": "year",
                      "yKeys": [
                        "option1",
                        "option2"
                      ],
                      "points": [
                        {
                          "year": 1,
                          "option1": 3835.2,
                          "option2": 12.4
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/plan_monthly_budget": {
      "post": {
        "operationId": "plan_monthly_budget",
        "summary": "Summarize supplied income and expenses as a monthly household budget.",
        "description": "Build a monthly budget from actual income and expense items. Ask for missing values; never fabricate expenses. Disclose that entries without a frequency are treated as monthly.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "monthlyNetIncome": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Take-home monthly income, EUR (net of tax, social insurance and GESY); zero is valid but savings rate is unavailable."
                  },
                  "expenses": {
                    "type": "array",
                    "minItems": 1,
                    "description": "Expense items. Known catalogue keys (mortgageRent, groceries, netflix, fuel, ...) are tiered automatically; otherwise pass an explicit tier.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string",
                          "description": "Catalogue key or free-form label."
                        },
                        "amount": {
                          "type": "number",
                          "minimum": 0,
                          "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                        },
                        "frequency": {
                          "type": "string",
                          "enum": [
                            "monthly",
                            "weekly",
                            "quarterly",
                            "semiannual",
                            "yearly",
                            "oneoff"
                          ],
                          "default": "monthly",
                          "description": "Payment frequency; everything is normalised to monthly. Default monthly."
                        },
                        "tier": {
                          "type": "string",
                          "enum": [
                            "T1",
                            "T2",
                            "T3",
                            "T4"
                          ],
                          "description": "Override the automatic tier."
                        },
                        "category": {
                          "type": "string",
                          "description": "Optional grouping label (housing, transportation, ...)."
                        }
                      },
                      "additionalProperties": false,
                      "required": [
                        "key",
                        "amount"
                      ]
                    }
                  },
                  "monthlyInvestments": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Recurring monthly investments/savings, EUR."
                  },
                  "targetSavingsRate": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Savings-rate goal as a percent of net income."
                  },
                  "projectionYears": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 40,
                    "default": 10,
                    "description": "Horizon of the surplus projection (default 10)."
                  },
                  "expectedAnnualReturn": {
                    "type": "number",
                    "default": 0,
                    "description": "Assumed annual return on invested surplus, percent (default 0)."
                  }
                },
                "required": [
                  "monthlyNetIncome",
                  "expenses"
                ]
              },
              "example": {
                "monthlyNetIncome": 3200,
                "expenses": [
                  {
                    "key": "mortgageRent",
                    "amount": 900,
                    "frequency": "monthly"
                  },
                  {
                    "key": "groceries",
                    "amount": 500,
                    "frequency": "monthly"
                  },
                  {
                    "key": "carInsurance",
                    "amount": 480,
                    "frequency": "yearly"
                  },
                  {
                    "key": "restaurantsDining",
                    "amount": 60,
                    "frequency": "weekly"
                  }
                ],
                "monthlyInvestments": 400,
                "targetSavingsRate": 25,
                "projectionYears": 10,
                "expectedAnnualReturn": 5
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Monthly expenses total €1,700.00 against €3,200.00 of net income, leaving €1,100.00 of surplus after €400.00 of investments (savings rate 46.9%)."
                    }
                  ],
                  "structuredContent": {
                    "monthlyNetIncome": 3200,
                    "totalMonthlyExpenses": 1700,
                    "tierTotals": {
                      "T1": 900,
                      "T2": 540,
                      "T3": 0,
                      "T4": 260
                    },
                    "categoryTotals": {
                      "uncategorised": 1700
                    },
                    "monthlyInvestments": 400,
                    "disposableIncome": 1500,
                    "monthlySurplus": 1100,
                    "savingsRate": 46.88,
                    "annualExpenses": 20400,
                    "largestLeak": {
                      "key": "restaurantsDining",
                      "amount": 260
                    },
                    "discretionaryTotal": 260,
                    "targetSavingsRate": 25,
                    "targetMonthlySavings": 800,
                    "savingsGap": -700
                  },
                  "series": [
                    {
                      "chartId": "surplusProjection",
                      "title": "Projected cumulative surplus",
                      "xKey": "year",
                      "yKeys": [
                        "cumulativeSurplus"
                      ],
                      "points": [
                        {
                          "year": 1,
                          "cumulativeSurplus": 18412.5
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/analyze_portfolio": {
      "post": {
        "operationId": "analyze_portfolio",
        "summary": "Analyses an investment portfolio from its transaction history: net invested capital, current value, absolute return, chain-linked time-weighted return (TWR), CAGR on initial invested capital, per-sub-portfolio breakdown and allocation shares, with multi-currency support via per-transaction FX rates.",
        "description": "Analyze an investment portfolio from actual transactions or holdings and current valuations. Ask for missing records and FX rates where currencies differ; never create holdings or transactions.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "portfolioName": {
                    "type": "string",
                    "description": "Optional label for the portfolio."
                  },
                  "baseCurrency": {
                    "type": "string",
                    "description": "Reporting currency (e.g. EUR). Transactions in another currency require fxRate."
                  },
                  "asOfDate": {
                    "type": "string",
                    "description": "Optional ISO date (YYYY-MM-DD) used as the CAGR end date. Defaults to today."
                  },
                  "subPortfolios": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 50,
                    "description": "One entry per account, broker or strategy sleeve.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "currency": {
                          "type": "string",
                          "description": "Currency the transactions are denominated in."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "cash_flow",
                            "holdings"
                          ],
                          "description": "cash_flow: transaction ledger sleeve. holdings: EOD snapshot sleeve valued from holdings closes (transactions may be empty)."
                        },
                        "cashBalance": {
                          "type": "number",
                          "minimum": 0,
                          "description": "Uninvested cash swept into a holdings sleeve's value (counts 1:1 on invested and current value)."
                        },
                        "cashLabel": {
                          "type": "string",
                          "description": "Cash bucket label (e.g. emergency, savings, collateral, current)."
                        },
                        "holdings": {
                          "type": "array",
                          "maxItems": 200,
                          "description": "Positions for a holdings sleeve. Omitted avgCostPrice tracks returns from today (day-1 return 0%).",
                          "items": {
                            "type": "object",
                            "properties": {
                              "symbol": {
                                "type": "string",
                                "description": "Ticker, e.g. VWCE."
                              },
                              "yahooSymbol": {
                                "type": "string",
                                "description": "Resolved Yahoo symbol, e.g. VWCE.MI."
                              },
                              "name": {
                                "type": "string"
                              },
                              "shares": {
                                "type": "number",
                                "exclusiveMinimum": 0
                              },
                              "avgCostPrice": {
                                "type": "number",
                                "exclusiveMinimum": 0
                              },
                              "currency": {
                                "type": "string"
                              },
                              "currentPrice": {
                                "type": "number",
                                "exclusiveMinimum": 0
                              },
                              "fxRate": {
                                "type": "number",
                                "exclusiveMinimum": 0,
                                "description": "Legacy alias for fxRateToBase."
                              },
                              "asOfDate": {
                                "type": "string",
                                "description": "Bar date of currentPrice (YYYY-MM-DD)."
                              },
                              "fxRateToBase": {
                                "type": "number",
                                "exclusiveMinimum": 0
                              },
                              "isin": {
                                "type": "string"
                              },
                              "acquiredDate": {
                                "type": "string",
                                "description": "Vintage powering per-holding CAGR (YYYY-MM-DD)."
                              },
                              "ownershipShare": {
                                "type": "number",
                                "minimum": 0,
                                "maximum": 1
                              },
                              "notes": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": false,
                            "required": [
                              "symbol",
                              "shares",
                              "currentPrice"
                            ]
                          }
                        },
                        "transactions": {
                          "type": "array",
                          "minItems": 0,
                          "maxItems": 1000,
                          "description": "Ledger for cash_flow sleeves. May be empty for holdings sleeves (valued from holdings closes).",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": {
                                "type": "string",
                                "description": "ISO date (YYYY-MM-DD)."
                              },
                              "type": {
                                "type": "string",
                                "enum": [
                                  "Deposit",
                                  "Withdrawal",
                                  "Value"
                                ],
                                "description": "Deposit/Withdrawal are cash flows; Value is a portfolio valuation snapshot."
                              },
                              "amount": {
                                "type": "number",
                                "minimum": 0,
                                "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                              },
                              "fxRate": {
                                "type": "number",
                                "exclusiveMinimum": 0,
                                "description": "Units of sub-portfolio currency per one unit of base currency. Required when currencies differ."
                              }
                            },
                            "additionalProperties": false,
                            "required": [
                              "date",
                              "type",
                              "amount"
                            ]
                          }
                        }
                      },
                      "required": [
                        "name",
                        "currency"
                      ],
                      "allOf": [
                        {
                          "if": {
                            "properties": {
                              "type": {
                                "const": "holdings"
                              }
                            },
                            "required": [
                              "type"
                            ]
                          },
                          "then": {
                            "required": [
                              "holdings"
                            ]
                          }
                        },
                        {
                          "if": {
                            "properties": {
                              "type": {
                                "const": "cash_flow"
                              }
                            },
                            "required": [
                              "type"
                            ]
                          },
                          "then": {
                            "required": [
                              "transactions"
                            ]
                          }
                        }
                      ]
                    }
                  }
                },
                "required": [
                  "baseCurrency",
                  "subPortfolios"
                ]
              },
              "example": {
                "portfolioName": "Family portfolio",
                "baseCurrency": "EUR",
                "asOfDate": "2026-01-01",
                "subPortfolios": [
                  {
                    "name": "ETF core",
                    "currency": "EUR",
                    "transactions": [
                      {
                        "date": "2021-01-04",
                        "type": "Deposit",
                        "amount": 20000
                      },
                      {
                        "date": "2023-01-04",
                        "type": "Deposit",
                        "amount": 10000
                      },
                      {
                        "date": "2025-12-31",
                        "type": "Value",
                        "amount": 41500
                      }
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Portfolio \"Family portfolio\" (EUR) is worth 41500.00 EUR against 30000.00 EUR of net invested capital — a gain of 11500.00 EUR (38.33% absolute, TWR unavailable because a valuation is missing before the later deposit, 6.79% CAGR on initial invested capital)."
                    }
                  ],
                  "structuredContent": {
                    "portfolioName": "Family portfolio",
                    "baseCurrency": "EUR",
                    "totalInvested": 30000,
                    "totalInitialInvested": 30000,
                    "currentValue": 41500,
                    "totalGain": 11500,
                    "absoluteReturn": 38.33,
                    "timeWeightedReturn": null,
                    "twrUnavailableReason": "Combined valuations are required immediately before each later external flow and at the end date.",
                    "cagr": 6.79,
                    "firstDepositDate": "2021-01-04",
                    "subPortfolios": [
                      {
                        "name": "ETF core",
                        "currency": "EUR",
                        "invested": 30000,
                        "initialInvested": 30000,
                        "currentValue": 41500,
                        "gain": 11500,
                        "absoluteReturn": 38.33,
                        "timeWeightedReturn": null,
                        "twrUnavailableReason": "A valuation is required immediately before each later external flow and at the end date.",
                        "cagr": 6.79,
                        "allocationShare": 100,
                        "firstDepositDate": "2021-01-04",
                        "deposits": 30000,
                        "withdrawals": 0
                      }
                    ]
                  },
                  "series": [
                    {
                      "chartId": "valueByDate",
                      "title": "Total portfolio value by valuation date",
                      "xKey": "date",
                      "yKeys": [
                        "totalValue"
                      ],
                      "points": [
                        {
                          "date": "2025-12-31",
                          "totalValue": 41500
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/simulate_life_insurance_flush": {
      "post": {
        "operationId": "simulate_life_insurance_flush",
        "summary": "Project withdrawals from an existing Cyprus life-insurance policy.",
        "description": "Model withdrawals from an existing Cyprus life-insurance policy. Ask for actual policy terms, tax rate, historical records and future premiums or withdrawals. Never generate policy history; identify forecast returns as assumptions.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contractStartYear": {
                    "type": "integer",
                    "description": "Calendar year the policy started. Partial surrenders are only tax-free from the 4th policy year."
                  },
                  "age": {
                    "type": "integer",
                    "minimum": 18,
                    "maximum": 90,
                    "description": "Current age of the policyholder."
                  },
                  "gender": {
                    "type": "string",
                    "enum": [
                      "male",
                      "female"
                    ],
                    "description": "Used to look up mortality rates."
                  },
                  "capitalSumInsured": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Death benefit / sum insured, EUR. Mortality cost applies to the amount at risk above the fund value."
                  },
                  "aumFee": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 10,
                    "description": "Annual management fee as a percent of fund value."
                  },
                  "monthlyFee": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Fixed policy fee charged each month, EUR."
                  },
                  "investmentReturn": {
                    "type": "number",
                    "description": "Annual percentage value (e.g. 2.5 for 2.5%). Supply the actual rate unless the user accepts a stated modelling default. Expected annual return inside the policy."
                  },
                  "taxBracket": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 60,
                    "description": "Marginal income tax rate applied to taxable surrender amounts and to premium relief, percent."
                  },
                  "reinvestWithdrawals": {
                    "type": "boolean",
                    "description": "When true, net withdrawals are reinvested in a broker account and IRR is computed on combined wealth."
                  },
                  "brokerReturnRate": {
                    "type": "number",
                    "description": "Annual return of the broker account, percent (used with useDifferentBrokerReturn)."
                  },
                  "useDifferentBrokerReturn": {
                    "type": "boolean",
                    "description": "Use brokerReturnRate instead of investmentReturn for the broker account."
                  },
                  "historicalData": {
                    "type": "array",
                    "minItems": 1,
                    "description": "Actual policy history; the last entry's endingBalance is the simulation's opening balance, and the 3/4-year lookbacks drive the safe limit.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "year": {
                          "type": "integer"
                        },
                        "endingBalance": {
                          "type": "number",
                          "minimum": 0,
                          "description": "Fund value at 31 December, EUR."
                        },
                        "premiumsPaid": {
                          "type": "number",
                          "minimum": 0,
                          "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                        },
                        "withdrawalsMade": {
                          "type": "number",
                          "minimum": 0,
                          "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                        }
                      },
                      "additionalProperties": false,
                      "required": [
                        "year",
                        "endingBalance",
                        "premiumsPaid",
                        "withdrawalsMade"
                      ]
                    }
                  },
                  "projections": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 60,
                    "description": "Future years to simulate.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "year": {
                          "type": "integer"
                        },
                        "monthlyPremium": {
                          "type": "number",
                          "minimum": 0,
                          "description": "EUR amount. Supply the actual value when applicable; use 0 only when confirmed to be zero."
                        },
                        "plannedWithdrawal": {
                          "type": "number",
                          "minimum": 0,
                          "description": "Withdrawal to attempt in this year (userInput scenario only)."
                        },
                        "isSelfFunded": {
                          "type": "boolean",
                          "description": "Premium funded by withdrawing from the policy itself; costs a 5% spread each month."
                        }
                      },
                      "required": [
                        "year",
                        "monthlyPremium"
                      ]
                    }
                  },
                  "scenario": {
                    "type": "string",
                    "enum": [
                      "maxTaxFree",
                      "userInput",
                      "noWithdrawals"
                    ],
                    "description": "Which scenario to report as the primary result (default userInput). All three are always returned for comparison."
                  }
                },
                "required": [
                  "contractStartYear",
                  "age",
                  "gender",
                  "capitalSumInsured",
                  "aumFee",
                  "monthlyFee",
                  "investmentReturn",
                  "taxBracket",
                  "historicalData",
                  "projections"
                ]
              },
              "example": {
                "contractStartYear": 2025,
                "age": 45,
                "gender": "male",
                "capitalSumInsured": 0,
                "aumFee": 0,
                "monthlyFee": 0,
                "investmentReturn": 0,
                "taxBracket": 20,
                "reinvestWithdrawals": true,
                "historicalData": [
                  {
                    "year": 2025,
                    "endingBalance": 100,
                    "premiumsPaid": 0,
                    "withdrawalsMade": 0
                  }
                ],
                "projections": [
                  {
                    "year": 2026,
                    "monthlyPremium": 10,
                    "plannedWithdrawal": 20
                  }
                ],
                "scenario": "userInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Scenario \"userInput\": final household value €218.00 after a €20.00 gross withdrawal, comprising €200.00 policy balance and €18.00 broker balance, with €0.00 fees, €0.00 mortality cost and €2.00 surrender tax. Full-horizon household IRR excluding premium tax relief: -0.91%; including year-end premium tax relief: 10.00%."
                    }
                  ],
                  "structuredContent": {
                    "scenario": "userInput",
                    "finalBalance": 218,
                    "finalPolicyBalance": 200,
                    "finalBrokerBalance": 18,
                    "netWithdrawalsPaidOut": 0,
                    "totalWithdrawn": 20,
                    "totalFeesPaid": 0,
                    "totalMortalityCost": 0,
                    "totalTaxPaid": 2,
                    "totalTaxSaved": 24,
                    "totalSelfFundedCost": 0,
                    "irr": -0.91,
                    "irrPerspective": "Full-horizon household cash flows: external premiums and net withdrawals paid out, terminal policy and broker balances; surrender tax included, premium tax relief excluded.",
                    "irrUnavailableReason": null,
                    "irrWithTax": 10,
                    "irrWithoutTax": -0.91,
                    "irrWithTaxPerspective": "Full-horizon household cash flows, including premium tax relief received at each year end and surrender tax paid.",
                    "irrWithoutTaxPerspective": "Full-horizon household cash flows, excluding premium tax relief and including surrender tax paid.",
                    "safeLimitByYear": [
                      {
                        "year": 2026,
                        "safeLimit": 0,
                        "balance4YrAgo": 0,
                        "priorPremiums3Yr": 0,
                        "priorWithdrawals3Yr": 0,
                        "netExcessWithdrawals": 0,
                        "policyMature": false
                      }
                    ],
                    "scenarioComparison": [
                      {
                        "type": "maxTaxFree",
                        "finalBalance": 220,
                        "finalPolicyBalance": 220,
                        "finalBrokerBalance": 0,
                        "netWithdrawalsPaidOut": 0,
                        "totalWithdrawn": 0,
                        "totalTaxPaid": 0,
                        "irr": 0,
                        "irrWithTax": 10.91,
                        "irrWithoutTax": 0
                      },
                      {
                        "type": "userInput",
                        "finalBalance": 218,
                        "finalPolicyBalance": 200,
                        "finalBrokerBalance": 18,
                        "netWithdrawalsPaidOut": 0,
                        "totalWithdrawn": 20,
                        "totalTaxPaid": 2,
                        "irr": -0.91,
                        "irrWithTax": 10,
                        "irrWithoutTax": -0.91
                      },
                      {
                        "type": "noWithdrawals",
                        "finalBalance": 220,
                        "finalPolicyBalance": 220,
                        "finalBrokerBalance": 0,
                        "netWithdrawalsPaidOut": 0,
                        "totalWithdrawn": 0,
                        "totalTaxPaid": 0,
                        "irr": 0,
                        "irrWithTax": 10.91,
                        "irrWithoutTax": 0
                      }
                    ],
                    "mortalityDataAvailable": false
                  },
                  "series": [
                    {
                      "chartId": "balanceByYear",
                      "title": "Policy balance, withdrawals and tax by year",
                      "xKey": "year",
                      "yKeys": [
                        "endingBalance",
                        "withdrawal",
                        "safeLimit",
                        "taxDue"
                      ],
                      "points": [
                        {
                          "year": 2026,
                          "startingBalance": 100,
                          "premium": 120,
                          "withdrawal": 20,
                          "safeLimit": 0,
                          "taxableAmount": 10,
                          "taxDue": 2,
                          "taxSaved": 24,
                          "mortalityCost": 0,
                          "aumFee": 0,
                          "fixedFee": 0,
                          "selfFundedCost": 0,
                          "endingBalance": 200,
                          "brokerEndValue": 18,
                          "combinedEndValue": 218,
                          "cumulativeWithdrawn": 20,
                          "netWithdrawalPaidOut": 0,
                          "cumulativeNetWithdrawalsPaidOut": 0,
                          "maxAvailableWithdrawal": 220,
                          "hasInsufficientFunds": false,
                          "isSelfFunded": false,
                          "annualizedReturn": 13.91,
                          "annualizedReturnWithoutTax": -1.25
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/audit_mortgage_statement": {
      "post": {
        "operationId": "audit_mortgage_statement",
        "summary": "Audit an actual mortgage statement against loan activity.",
        "description": "Audit supplied mortgage statement rows. Ask for usable interest rates and balance checkpoints. Report fitted day-count and capitalization conventions as estimates, not confirmed bank terms.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "rows": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 2000,
                    "description": "Parsed statement rows in chronological order. At least one row must carry ratePct.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "date": {
                          "type": "string",
                          "description": "ISO date (YYYY-MM-DD)."
                        },
                        "description": {
                          "type": "string"
                        },
                        "signedAmount": {
                          "type": "number",
                          "description": "Positive increases the outstanding balance (drawdown, interest posting, fee); negative reduces it (payment)."
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "drawdown",
                            "payment",
                            "interest_post",
                            "fee",
                            "adjustment",
                            "other"
                          ],
                          "description": "Row type. interest_post rows are the bank's own interest charges and are what the audit compares against."
                        },
                        "balanceAfter": {
                          "type": "number",
                          "description": "Outstanding balance the statement reports after this row, EUR. Used as the fit checkpoint."
                        },
                        "ratePct": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 30,
                          "description": "Annual nominal rate in effect from this row onwards, percent."
                        }
                      },
                      "additionalProperties": false,
                      "required": [
                        "date",
                        "signedAmount"
                      ]
                    }
                  },
                  "topN": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10,
                    "default": 3,
                    "description": "How many ranked candidate conventions to return (default 3)."
                  },
                  "includeRowDetail": {
                    "type": "boolean",
                    "description": "Include the per-row expected balance / delta / flag detail (can be large)."
                  },
                  "rules": {
                    "type": "object",
                    "description": "Skip the grid search and test one explicit convention.",
                    "properties": {
                      "dayCount": {
                        "oneOf": [
                          {
                            "type": "number",
                            "enum": [
                              360,
                              365
                            ]
                          },
                          {
                            "type": "string",
                            "enum": [
                              "actual"
                            ]
                          }
                        ]
                      },
                      "capitalization": {
                        "type": "string",
                        "enum": [
                          "daily",
                          "monthly",
                          "quarterly",
                          "semiannual",
                          "annual"
                        ]
                      },
                      "capitalizationAnchor": {
                        "type": "string",
                        "enum": [
                          "month_end",
                          "first_disbursement",
                          "fixed_dates"
                        ]
                      },
                      "fixedCapDates": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "description": "MM-DD"
                        }
                      },
                      "dailyRounding": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "Decimals for daily interest rounding, or null for exact."
                      },
                      "ignoreBankCapRows": {
                        "type": "boolean",
                        "description": "Do not add the bank's own interest postings to the simulated balance (default true)."
                      }
                    }
                  }
                },
                "required": [
                  "rows"
                ]
              },
              "example": {
                "topN": 3,
                "rows": [
                  {
                    "date": "2024-01-15",
                    "description": "Loan drawdown",
                    "signedAmount": 200000,
                    "kind": "drawdown",
                    "balanceAfter": 200000,
                    "ratePct": 4.25
                  },
                  {
                    "date": "2024-02-29",
                    "description": "Interest",
                    "signedAmount": 1050.5,
                    "kind": "interest_post",
                    "balanceAfter": 200000
                  },
                  {
                    "date": "2024-03-01",
                    "description": "Instalment",
                    "signedAmount": -1200,
                    "kind": "payment",
                    "balanceAfter": 198800
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Representative best-fit convention: Actual/365, semi-annual (06-30 / 12-31) capitalisation, exact rounding (RMS balance error €0 over 3 checkpoints). The bank posted €1,050.5 of interest versus €1,071.23 expected — no overcharge (€20.73 in your favour). The fit is ambiguous: 18 conventions are within €0.01 RMS; the displayed best fit is representative. Equivalent candidates imply expected interest from €1,068.12 to €1,086.11 and net overcharge from €-35.61 to €-17.62."
                    }
                  ],
                  "structuredContent": {
                    "fitStatus": "ambiguous",
                    "equivalentCandidateCount": 18,
                    "equivalentCandidates": [
                      {
                        "rulesLabel": "Actual/365, semi-annual (06-30 / 12-31) capitalisation, exact rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -20.73,
                        "expectedInterest": 1071.23
                      },
                      {
                        "rulesLabel": "Actual/365, semi-annual (07-01 / 01-01) capitalisation, exact rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -20.73,
                        "expectedInterest": 1071.23
                      },
                      {
                        "rulesLabel": "Actual/365, semi-annual (06-30 / 12-31) capitalisation, 2-decimal daily rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -20.84,
                        "expectedInterest": 1071.34
                      },
                      {
                        "rulesLabel": "Actual/365, semi-annual (07-01 / 01-01) capitalisation, 2-decimal daily rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -20.84,
                        "expectedInterest": 1071.34
                      },
                      {
                        "rulesLabel": "Actual/365, annual capitalisation, exact rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -20.73,
                        "expectedInterest": 1071.23
                      },
                      {
                        "rulesLabel": "Actual/365, annual capitalisation, 2-decimal daily rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -20.84,
                        "expectedInterest": 1071.34
                      },
                      {
                        "rulesLabel": "Actual/360, semi-annual (06-30 / 12-31) capitalisation, exact rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -35.61,
                        "expectedInterest": 1086.11
                      },
                      {
                        "rulesLabel": "Actual/360, semi-annual (07-01 / 01-01) capitalisation, exact rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -35.61,
                        "expectedInterest": 1086.11
                      },
                      {
                        "rulesLabel": "Actual/360, semi-annual (06-30 / 12-31) capitalisation, 2-decimal daily rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -35.56,
                        "expectedInterest": 1086.06
                      },
                      {
                        "rulesLabel": "Actual/360, semi-annual (07-01 / 01-01) capitalisation, 2-decimal daily rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -35.56,
                        "expectedInterest": 1086.06
                      },
                      {
                        "rulesLabel": "Actual/360, annual capitalisation, exact rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -35.61,
                        "expectedInterest": 1086.11
                      },
                      {
                        "rulesLabel": "Actual/360, annual capitalisation, 2-decimal daily rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -35.56,
                        "expectedInterest": 1086.06
                      },
                      {
                        "rulesLabel": "Actual/Actual, semi-annual (06-30 / 12-31) capitalisation, exact rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -17.81,
                        "expectedInterest": 1068.31
                      },
                      {
                        "rulesLabel": "Actual/Actual, semi-annual (07-01 / 01-01) capitalisation, exact rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -17.81,
                        "expectedInterest": 1068.31
                      },
                      {
                        "rulesLabel": "Actual/Actual, semi-annual (06-30 / 12-31) capitalisation, 2-decimal daily rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -17.62,
                        "expectedInterest": 1068.12
                      },
                      {
                        "rulesLabel": "Actual/Actual, semi-annual (07-01 / 01-01) capitalisation, 2-decimal daily rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -17.62,
                        "expectedInterest": 1068.12
                      },
                      {
                        "rulesLabel": "Actual/Actual, annual capitalisation, exact rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -17.81,
                        "expectedInterest": 1068.31
                      },
                      {
                        "rulesLabel": "Actual/Actual, annual capitalisation, 2-decimal daily rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -17.62,
                        "expectedInterest": 1068.12
                      }
                    ],
                    "expectedInterestRange": {
                      "minimum": 1068.12,
                      "maximum": 1086.11
                    },
                    "netOverchargeRange": {
                      "minimum": -35.61,
                      "maximum": -17.62
                    },
                    "bestFitRules": {
                      "dayCount": 365,
                      "capitalization": "semiannual",
                      "capitalizationAnchor": "fixed_dates",
                      "fixedCapDates": [
                        "06-30",
                        "12-31"
                      ],
                      "dailyRounding": null,
                      "ignoreBankCapRows": true
                    },
                    "bestFitLabel": "Actual/365, semi-annual (06-30 / 12-31) capitalisation, exact rounding",
                    "bankInterest": 1050.5,
                    "expectedInterest": 1071.23,
                    "netOvercharge": -20.73,
                    "finalDelta": 0,
                    "rmsDelta": 0,
                    "observations": 3,
                    "rowsAnalyzed": 3,
                    "flaggedRows": 0,
                    "periodStart": "2024-01-15",
                    "periodEnd": "2024-03-01",
                    "rankedCandidates": [
                      {
                        "rulesLabel": "Actual/365, semi-annual (06-30 / 12-31) capitalisation, exact rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -20.73,
                        "expectedInterest": 1071.23
                      },
                      {
                        "rulesLabel": "Actual/365, semi-annual (07-01 / 01-01) capitalisation, exact rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -20.73,
                        "expectedInterest": 1071.23
                      },
                      {
                        "rulesLabel": "Actual/365, semi-annual (06-30 / 12-31) capitalisation, 2-decimal daily rounding",
                        "rmsDelta": 0,
                        "netOvercharge": -20.84,
                        "expectedInterest": 1071.34
                      }
                    ],
                    "assumptions": []
                  },
                  "series": [
                    {
                      "chartId": "candidateFit",
                      "title": "Candidate conventions ranked by balance error",
                      "xKey": "rulesLabel",
                      "yKeys": [
                        "rmsDelta",
                        "netOvercharge"
                      ],
                      "points": [
                        {
                          "rulesLabel": "Actual/365, semi-annual (06-30 / 12-31) capitalisation, exact rounding",
                          "rmsDelta": 0,
                          "netOvercharge": -20.73,
                          "expectedInterest": 1071.23
                        },
                        {
                          "rulesLabel": "Actual/365, semi-annual (07-01 / 01-01) capitalisation, exact rounding",
                          "rmsDelta": 0,
                          "netOvercharge": -20.73,
                          "expectedInterest": 1071.23
                        },
                        {
                          "rulesLabel": "Actual/365, semi-annual (06-30 / 12-31) capitalisation, 2-decimal daily rounding",
                          "rmsDelta": 0,
                          "netOvercharge": -20.84,
                          "expectedInterest": 1071.34
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/parse_portfolio_csv": {
      "post": {
        "operationId": "parse_portfolio_csv",
        "summary": "Turns pasted broker CSV or ledger text into analyze_portfolio transactions.",
        "description": "Extract transactions from pasted broker CSV or ledger text. Ask for the actual base currency and report missing or unreadable values; never create transactions or assume EUR.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Pasted broker CSV or ledger lines (date + type + amount per row)."
                  },
                  "baseCurrency": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Actual base currency used for the parsed portfolio. Required; do not assume EUR."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "text",
                  "baseCurrency"
                ]
              },
              "example": {
                "text": "2024-01-15, Deposit, 5000\n2024-06-20, Deposit, 2500\n",
                "baseCurrency": "EUR"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Parsed 2 portfolio transactions across 1 sub-portfolio. Send subPortfolios straight to analyze_portfolio."
                    }
                  ],
                  "structuredContent": {
                    "transactions": [
                      {
                        "date": "2024-01-15",
                        "type": "Deposit",
                        "amount": 5000
                      },
                      {
                        "date": "2024-06-20",
                        "type": "Deposit",
                        "amount": 2500
                      }
                    ],
                    "subPortfolios": [
                      {
                        "name": "default",
                        "currency": "EUR",
                        "transactions": []
                      }
                    ],
                    "baseCurrency": "EUR",
                    "parsedRows": 2,
                    "skippedRows": 0,
                    "parseConfidence": 1
                  },
                  "series": []
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/parse_mortgage_statement_text": {
      "post": {
        "operationId": "parse_mortgage_statement_text",
        "summary": "Turns pasted bank mortgage-statement rows into audit_mortgage_statement inputs.",
        "description": "Extract rows from pasted mortgage statement text. Use only supplied values; report ambiguous dates, amounts or rates for clarification and never fill missing records.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Pasted statement lines (date + description + amount per row, optional balance and rate%)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "text"
                ]
              },
              "example": {
                "text": "2024-01-15 Instalment -850.00 Balance 120000\n"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Parsed 1 mortgage statement row. Send rows straight to audit_mortgage_statement."
                    }
                  ],
                  "structuredContent": {
                    "rows": [
                      {
                        "date": "2024-01-15",
                        "description": "Instalment",
                        "signedAmount": -850,
                        "kind": "payment",
                        "balanceAfter": 120000
                      }
                    ],
                    "parsedRows": 1,
                    "skippedRows": 0,
                    "parseConfidence": 1
                  },
                  "series": []
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/tools/optimize_company_director_remuneration": {
      "post": {
        "operationId": "optimize_company_director_remuneration",
        "summary": "Optimizes Cyprus LTD company-director remuneration: finds the salary-vs-dividend split with maximum net cash in pocket.",
        "description": "Compare Cyprus LTD director salary and dividend options. Ask for company revenue or profit, expenses, tax year and domicile status. Disclose the default administration cost.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "corporateGrossProfit": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Annual company turnover/revenue in EUR, before operating expenses."
                  },
                  "operatingExpenses": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Annual deductible operating expenses in EUR."
                  },
                  "annualCorporateAdminCost": {
                    "type": "number",
                    "minimum": 0,
                    "default": 2000,
                    "description": "Annual corporate admin, audit and compliance costs in EUR (Cyprus Companies Law Cap. 113). Defaults to 2000."
                  },
                  "taxYear": {
                    "type": "string",
                    "enum": [
                      "2025",
                      "2026"
                    ],
                    "description": "Tax/legislation year. Supported: 2025, 2026."
                  },
                  "isNonDomiciled": {
                    "type": "boolean",
                    "description": "Non-dom status; exempts dividends from SDC."
                  },
                  "directorSalaryAllocation": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Optional fixed director salary in EUR; omit to run the solver for the optimal split."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "corporateGrossProfit",
                  "operatingExpenses",
                  "taxYear",
                  "isNonDomiciled"
                ]
              },
              "example": {
                "corporateGrossProfit": 100000,
                "operatingExpenses": 20000,
                "annualCorporateAdminCost": 2000,
                "taxYear": "2025",
                "isNonDomiciled": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolResponse"
                },
                "example": {
                  "content": [
                    {
                      "type": "text",
                      "text": "Optimal LTD split on €78,000 available profit: salary €22,000 + dividend €46,035.50 → net cash €56,470.52 (corporate tax €6,576.50, personal taxes €11,564.98, employer €3,388.00)."
                    }
                  ],
                  "structuredContent": {
                    "optimalSalary": 22000,
                    "optimalDividend": 46035.5,
                    "corporateTax": 6576.5,
                    "personalTaxes": 11564.98,
                    "employerContributions": 3388,
                    "employerBreakdown": {
                      "socialInsurance": 1936,
                      "redundancyFund": 264,
                      "trainingFund": 110,
                      "socialCohesionFund": 440,
                      "gesyEmployer": 638,
                      "total": 3388
                    },
                    "netCash": 56470.52,
                    "comparativeDeltaVsSole": null
                  },
                  "series": []
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Use fieldErrors and hint to ask for corrected inputs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    }
  }
}
