{
  "openapi": "3.1.1",
  "info": {
    "title": "Ledgerly Early Retirement Bridge API",
    "version": "1.0.0",
    "summary": "Retire early? The years and money between leaving work and the state pension.",
    "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://ledgerlyfirebridge.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Retire early? The years and money between leaving work and the state pension.",
        "description": "Plans the bridge from early retirement (FIRE) to the statutory pension: the pension age by year of birth for Germany, Austria, Switzerland, the Netherlands, the UK and the US (editable, with sources), locked pension savings with their access age, the capital needed when you stop, a year-by-year plan and the earliest age that works.\n\nMethodology:\n- Everything is in today’s money with a real (after-inflation) return. Each year: withdraw spending minus the state pension at the start, then add the return and, while working, the contributions at the end of the year.\n- Withdrawals come from the savings you can use first; locked pension savings (401(k)/IRA, Riester/Rürup, UK personal pensions) only from their access age. A shortfall before that age means the bridge fails even if the total would last.\n- Capital needed when you stop = present value of the bridge (full spending until the pension age) plus the gap after it (spending − pension) until the plan ends. Pension ages by year of birth for Germany, Austria, Switzerland, Netherlands, United Kingdom, United States; the birthday is assumed in mid-year and every age can be overridden.\n- The earliest age that works is the first whole age at which the year-by-year plan never runs short. The 4 % rule (25 × spending) is shown as a reference only.\n\nA planning model, not advice: pension amounts drop when you stop contributing early, laws change, and returns are uncertain. Check your pension statement and the official rules.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "ledgerly_fire_bridge",
        "x-owner-app": "ledgerly",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LedgerlyFireBridgeInput"
              },
              "examples": {
                "example1": {
                  "summary": "Germany, born 1990, stop at 55",
                  "value": {
                    "country": "DE",
                    "birthYear": 1990,
                    "currentYear": 2026,
                    "currency": "EUR",
                    "fireAge": 55,
                    "annualSpending": 36000,
                    "statePensionPerYear": 18000,
                    "currentSavings": 150000,
                    "annualContribution": 24000,
                    "realReturnPercent": 3
                  }
                },
                "example2": {
                  "summary": "US, born 1985, 401(k) locked until 59½",
                  "value": {
                    "country": "US",
                    "birthYear": 1985,
                    "currentYear": 2026,
                    "currency": "USD",
                    "fireAge": 50,
                    "annualSpending": 60000,
                    "statePensionPerYear": 24000,
                    "currentSavings": 400000,
                    "annualContribution": 30000,
                    "lockedSavings": 350000,
                    "lockedContribution": 23000,
                    "realReturnPercent": 4
                  }
                },
                "example3": {
                  "summary": "Switzerland, woman born 1963",
                  "value": {
                    "country": "CH",
                    "pensionRules": "female",
                    "birthYear": 1963,
                    "currentYear": 2026,
                    "currency": "CHF",
                    "fireAge": 63,
                    "annualSpending": 50000,
                    "statePensionPerYear": 28000,
                    "currentSavings": 600000,
                    "annualContribution": 0,
                    "realReturnPercent": 2
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LedgerlyFireBridgeResult"
                }
              }
            }
          },
          "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"
                }
              }
            }
          }
        }
      },
      "LedgerlyFireBridgeInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "country": {
            "title": "Country of your state pension",
            "type": "string",
            "enum": [
              "DE",
              "AT",
              "CH",
              "NL",
              "GB",
              "US",
              "other"
            ],
            "default": "DE"
          },
          "pensionRules": {
            "title": "Pension age rules",
            "type": "string",
            "enum": [
              "general",
              "female"
            ],
            "default": "general"
          },
          "birthYear": {
            "title": "Year of birth",
            "type": "integer",
            "minimum": 1940,
            "maximum": 2015,
            "default": 1990
          },
          "currentYear": {
            "title": "Current year",
            "description": "Empty = this year.",
            "type": "integer",
            "minimum": 2000,
            "maximum": 2100
          },
          "currency": {
            "title": "Currency",
            "type": "string",
            "maxLength": 3,
            "default": "EUR"
          },
          "fireAge": {
            "title": "Age when you stop working",
            "type": "number",
            "minimum": 18,
            "maximum": 80,
            "default": 50
          },
          "pensionAge": {
            "title": "State pension age (empty = from the country rules)",
            "type": "number",
            "minimum": 50,
            "maximum": 80
          },
          "privateAccessAge": {
            "title": "Age from which locked pension savings can be used (empty = country default)",
            "type": "number",
            "minimum": 40,
            "maximum": 80
          },
          "endAge": {
            "title": "Plan until age",
            "type": "integer",
            "minimum": 60,
            "maximum": 110,
            "default": 95
          },
          "annualSpending": {
            "title": "Spending per year in retirement (today’s money)",
            "type": "number",
            "minimum": 0,
            "maximum": 100000000,
            "default": 36000
          },
          "statePensionPerYear": {
            "title": "Expected state pension per year (today’s money)",
            "description": "From your pension statement; leaving work early usually lowers it.",
            "type": "number",
            "minimum": 0,
            "maximum": 10000000,
            "default": 18000
          },
          "currentSavings": {
            "title": "Savings you can use any time",
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000000,
            "default": 150000
          },
          "annualContribution": {
            "title": "Added to those savings per year until you stop",
            "type": "number",
            "minimum": 0,
            "maximum": 10000000000,
            "default": 24000
          },
          "lockedSavings": {
            "title": "Locked pension savings today (401(k), Riester …)",
            "type": "number",
            "minimum": 0,
            "maximum": 1000000000000,
            "default": 0
          },
          "lockedContribution": {
            "title": "Added to locked savings per year until you stop",
            "type": "number",
            "minimum": 0,
            "maximum": 10000000000,
            "default": 0
          },
          "realReturnPercent": {
            "title": "Real return after inflation (% per year)",
            "type": "number",
            "minimum": -5,
            "maximum": 12,
            "default": 3
          }
        },
        "required": []
      },
      "LedgerlyFireBridgeResult": {
        "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",
              "currentAge",
              "fireAge",
              "pensionAge",
              "pensionAgeSource",
              "pensionAgeExpected",
              "privateAccessAge",
              "bridgeYears",
              "neededAtFire",
              "projectedAtFire",
              "sufficient",
              "depletedAge",
              "earliestFireAge",
              "fourPercentRuleTarget",
              "years"
            ],
            "properties": {
              "currency": {
                "type": "string"
              },
              "currentAge": {
                "type": "integer"
              },
              "fireAge": {
                "type": "number"
              },
              "pensionAge": {
                "type": "number"
              },
              "pensionAgeSource": {
                "type": "string",
                "enum": [
                  "input",
                  "country-rule"
                ]
              },
              "pensionAgeExpected": {
                "type": "boolean"
              },
              "privateAccessAge": {
                "type": "number"
              },
              "bridgeYears": {
                "type": "number"
              },
              "neededAtFire": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "bridge",
                  "afterPension",
                  "total",
                  "accessibleBeforeLockedAge"
                ],
                "properties": {
                  "bridge": {
                    "type": "number"
                  },
                  "afterPension": {
                    "type": "number"
                  },
                  "total": {
                    "type": "number"
                  },
                  "accessibleBeforeLockedAge": {
                    "type": "number"
                  }
                }
              },
              "projectedAtFire": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "accessible",
                  "locked",
                  "total"
                ],
                "properties": {
                  "accessible": {
                    "type": "number"
                  },
                  "locked": {
                    "type": "number"
                  },
                  "total": {
                    "type": "number"
                  }
                }
              },
              "sufficient": {
                "type": "boolean"
              },
              "depletedAge": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "earliestFireAge": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "fourPercentRuleTarget": {
                "type": "number"
              },
              "years": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "age",
                    "year",
                    "phase",
                    "accessibleStart",
                    "lockedStart",
                    "contribution",
                    "spending",
                    "pension",
                    "withdrawal",
                    "growth",
                    "accessibleEnd",
                    "lockedEnd",
                    "shortfall"
                  ],
                  "properties": {
                    "age": {
                      "type": "integer"
                    },
                    "year": {
                      "type": "integer"
                    },
                    "phase": {
                      "type": "string",
                      "enum": [
                        "saving",
                        "bridge",
                        "pension"
                      ]
                    },
                    "accessibleStart": {
                      "type": "number"
                    },
                    "lockedStart": {
                      "type": "number"
                    },
                    "contribution": {
                      "type": "number"
                    },
                    "spending": {
                      "type": "number"
                    },
                    "pension": {
                      "type": "number"
                    },
                    "withdrawal": {
                      "type": "number"
                    },
                    "growth": {
                      "type": "number"
                    },
                    "accessibleEnd": {
                      "type": "number"
                    },
                    "lockedEnd": {
                      "type": "number"
                    },
                    "shortfall": {
                      "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"
              }
            }
          }
        }
      }
    }
  }
}