{
  "openapi": "3.1.0",
  "info": {
    "title": "Actual Salary API",
    "version": "1.0.0",
    "description": "Read-only UK take-home pay estimates for the 2026/27 tax year, powered by the same calculation engine as actualsalary.co.uk."
  },
  "servers": [
    { "url": "https://actualsalary.co.uk" }
  ],
  "paths": {
    "/api/v1/take-home/": {
      "get": {
        "operationId": "calculateTakeHomePay",
        "summary": "Calculate UK take-home pay",
        "description": "Returns annual and monthly estimates. Salary and optional monetary refinements are annual GBP amounts.",
        "parameters": [
          {
            "name": "salary",
            "in": "query",
            "required": true,
            "description": "Regular annual gross salary in GBP, excluding bonus.",
            "schema": { "type": "number", "minimum": 0, "maximum": 9999999 },
            "example": 35000
          },
          {
            "name": "region",
            "in": "query",
            "description": "Income Tax region. A regional tax-code prefix takes precedence.",
            "schema": { "type": "string", "enum": ["rest-of-uk", "scotland"], "default": "rest-of-uk" }
          },
          {
            "name": "taxCode",
            "in": "query",
            "description": "Supported UK PAYE tax code.",
            "schema": { "type": "string", "default": "1257L" }
          },
          {
            "name": "pensionPercent",
            "in": "query",
            "description": "Employee pension percentage applied to regular gross salary, not bonus.",
            "schema": { "type": "number", "minimum": 0, "maximum": 100, "default": 5 }
          },
          {
            "name": "pensionMode",
            "in": "query",
            "schema": { "type": "string", "enum": ["salary-sacrifice", "net-pay"], "default": "salary-sacrifice" }
          },
          {
            "name": "studentLoan",
            "in": "query",
            "schema": { "type": "string", "enum": ["none", "plan-1", "plan-2", "plan-4", "plan-5"], "default": "none" }
          },
          {
            "name": "postgraduateLoan",
            "in": "query",
            "schema": { "type": "boolean", "default": false }
          },
          {
            "name": "bonus",
            "in": "query",
            "description": "Annual gross bonus in GBP.",
            "schema": { "type": "number", "minimum": 0, "maximum": 9999999, "default": 0 }
          },
          {
            "name": "otherSalarySacrifice",
            "in": "query",
            "description": "Annual non-pension salary sacrifice in GBP.",
            "schema": { "type": "number", "minimum": 0, "maximum": 9999999, "default": 0 }
          }
        ],
        "responses": {
          "200": {
            "description": "Calculated take-home estimate.",
            "headers": {
              "Cache-Control": { "schema": { "type": "string" } }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/TakeHomeResponse" }
              }
            }
          },
          "400": {
            "description": "One or more query parameters are invalid.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "MoneyBreakdown": {
        "type": "object",
        "properties": {
          "grossPay": { "type": "number" },
          "incomeTax": { "type": "number" },
          "nationalInsurance": { "type": "number" },
          "employeePension": { "type": "number" },
          "otherSalarySacrifice": { "type": "number" },
          "studentLoan": { "type": "number" },
          "postgraduateLoan": { "type": "number" },
          "takeHome": { "type": "number" },
          "totalDeductions": { "type": "number" }
        },
        "required": ["grossPay", "incomeTax", "nationalInsurance", "employeePension", "otherSalarySacrifice", "studentLoan", "postgraduateLoan", "takeHome", "totalDeductions"]
      },
      "TakeHomeResponse": {
        "type": "object",
        "properties": {
          "apiVersion": { "type": "string" },
          "taxYear": { "type": "string" },
          "currency": { "type": "string", "const": "GBP" },
          "basis": { "type": "string", "const": "annual" },
          "inputs": { "type": "object", "additionalProperties": true },
          "result": {
            "type": "object",
            "properties": {
              "annual": {
                "allOf": [
                  { "$ref": "#/components/schemas/MoneyBreakdown" },
                  {
                    "type": "object",
                    "properties": {
                      "taxablePay": { "type": "number" },
                      "personalAllowance": { "type": "number" }
                    },
                    "required": ["taxablePay", "personalAllowance"]
                  }
                ]
              },
              "monthly": { "$ref": "#/components/schemas/MoneyBreakdown" },
              "effectiveDeductionRatePercent": { "type": "number" },
              "takeHomeRatePercent": { "type": "number" }
            },
            "required": ["annual", "monthly", "effectiveDeductionRatePercent", "takeHomeRatePercent"]
          },
          "assumptions": { "type": "object", "additionalProperties": true },
          "links": { "type": "object", "additionalProperties": { "type": "string", "format": "uri" } }
        },
        "required": ["apiVersion", "taxYear", "currency", "basis", "inputs", "result", "assumptions", "links"]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string", "const": "invalid_request" },
              "message": { "type": "string" },
              "details": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "parameter": { "type": "string" },
                    "message": { "type": "string" }
                  },
                  "required": ["parameter", "message"]
                }
              }
            },
            "required": ["code", "message", "details"]
          }
        },
        "required": ["error"]
      }
    }
  }
}
