{
  "openapi": "3.1.1",
  "info": {
    "title": "Ledgerly Compound Growth Calculator API",
    "version": "1.0.0",
    "summary": "What your savings grow to with monthly contributions, fees and inflation — year by year.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://ledgerlycompoundgrowth.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "What your savings grow to with monthly contributions, fees and inflation — year by year.",
        "description": "Compound interest with a starting amount, monthly contributions (at the start or end of the month, with a yearly raise), monthly, yearly or daily compounding, yearly fees and inflation. Shows the final balance, the same in today’s money, how much you paid in, how much fees cost including the growth they take away, the doubling time and a year-by-year table. Part of Ledgerly’s Debt \u0026 Growth.\n\nMethodology:\n- Month by month: a contribution at the start of the month (if chosen), growth at the monthly rate, the fee (yearly percentage ÷ 12 of the balance), then a contribution at the end of the month (if chosen).\n- Monthly rate: rate ÷ 12 for monthly compounding, (1 + rate)^(1/12) − 1 for yearly compounding (the same yearly result), (1 + rate/365)^(365/12) − 1 for daily compounding.\n- The monthly contribution rises by the yearly raise at the start of every new year. Today’s money divides the balance by (1 + inflation)^years.\n- Lost to fees = the balance without fees minus the balance with fees: the fees themselves plus the growth they would have earned. Doubling time = ln 2 ÷ ln(1 + return after fees); the rule of 72 is shown for comparison.\n\nReturns are not guaranteed and change from year to year; this model uses one constant rate. It is not investment advice.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "ledgerly_compound_growth",
        "x-owner-app": "ledgerly",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LedgerlyCompoundGrowthInput"
              },
              "examples": {
                "example1": {
                  "summary": "10,000 plus 200 a month for 20 years at 6 %, 0.8 % fees",
                  "value": {
                    "currency": "EUR",
                    "startAmount": 10000,
                    "monthlyContribution": 200,
                    "years": 20,
                    "annualReturnPercent": 6,
                    "feePercent": 0.8,
                    "inflationPercent": 2
                  }
                },
                "example2": {
                  "summary": "Textbook check: 10,000 at 5 % compounded yearly for 10 years",
                  "value": {
                    "currency": "USD",
                    "startAmount": 10000,
                    "monthlyContribution": 0,
                    "years": 10,
                    "annualReturnPercent": 5,
                    "compounding": "yearly",
                    "inflationPercent": 0
                  }
                },
                "example3": {
                  "summary": "Start at 25: 150 a month, raised 3 % a year, 40 years",
                  "value": {
                    "currency": "EUR",
                    "startAmount": 0,
                    "monthlyContribution": 150,
                    "contributionTiming": "start",
                    "contributionIncreasePercent": 3,
                    "years": 40,
                    "annualReturnPercent": 5,
                    "feePercent": 0.2,
                    "inflationPercent": 2
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LedgerlyCompoundGrowthResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "LedgerlyCompoundGrowthInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "currency": {
            "title": "Currency",
            "description": "ISO code used for the labels, e.g. EUR, USD, GBP.",
            "type": "string",
            "maxLength": 3,
            "default": "EUR"
          },
          "startAmount": {
            "title": "Starting amount",
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000,
            "default": 10000
          },
          "monthlyContribution": {
            "title": "Added every month",
            "type": "number",
            "minimum": 0,
            "maximum": 10000000,
            "default": 200
          },
          "contributionTiming": {
            "title": "Added at the",
            "type": "string",
            "enum": [
              "end",
              "start"
            ],
            "default": "end"
          },
          "contributionIncreasePercent": {
            "title": "Raise of the monthly amount (% per year)",
            "type": "number",
            "minimum": 0,
            "maximum": 50,
            "default": 0
          },
          "years": {
            "title": "Years",
            "type": "integer",
            "minimum": 1,
            "maximum": 80,
            "default": 20
          },
          "annualReturnPercent": {
            "title": "Return (% per year, before fees)",
            "type": "number",
            "minimum": -20,
            "maximum": 30,
            "default": 6
          },
          "compounding": {
            "title": "Compounding",
            "type": "string",
            "enum": [
              "monthly",
              "yearly",
              "daily"
            ],
            "default": "monthly"
          },
          "feePercent": {
            "title": "Yearly fees (% of the balance)",
            "description": "Fund costs (TER), platform or advice fees, charged monthly on the balance.",
            "type": "number",
            "minimum": 0,
            "maximum": 10,
            "default": 0
          },
          "inflationPercent": {
            "title": "Inflation (% per year) for today’s money",
            "type": "number",
            "minimum": -5,
            "maximum": 30,
            "default": 2
          }
        },
        "required": []
      },
      "LedgerlyCompoundGrowthResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "currency",
              "years",
              "finalBalance",
              "finalBalanceToday",
              "totalContributed",
              "totalGrowth",
              "totalFees",
              "feeDrag",
              "netReturnPercent",
              "realReturnPercent",
              "doublingYears",
              "ruleOf72Years",
              "yearly"
            ],
            "properties": {
              "currency": {
                "type": "string"
              },
              "years": {
                "type": "integer"
              },
              "finalBalance": {
                "type": "number"
              },
              "finalBalanceToday": {
                "type": "number"
              },
              "totalContributed": {
                "type": "number"
              },
              "totalGrowth": {
                "type": "number"
              },
              "totalFees": {
                "type": "number"
              },
              "feeDrag": {
                "type": "number"
              },
              "netReturnPercent": {
                "type": "number"
              },
              "realReturnPercent": {
                "type": "number"
              },
              "doublingYears": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "ruleOf72Years": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "yearly": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "year",
                    "contributed",
                    "growth",
                    "fees",
                    "balance",
                    "balanceToday",
                    "totalContributed"
                  ],
                  "properties": {
                    "year": {
                      "type": "integer"
                    },
                    "contributed": {
                      "type": "number"
                    },
                    "growth": {
                      "type": "number"
                    },
                    "fees": {
                      "type": "number"
                    },
                    "balance": {
                      "type": "number"
                    },
                    "balanceToday": {
                      "type": "number"
                    },
                    "totalContributed": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}