{
  "openapi": "3.1.0",
  "info": {
    "title": "TaxLane Developer API",
    "version": "1.0.0",
    "description": "Free, no API key required — rate-limited to 50 requests/second (100 burst) shared across all endpoints, no per-caller tiers. The same math TaxLane's tax calculators use, as a JSON API."
  },
  "servers": [
    {
      "url": "https://api.taxlane.ng"
    }
  ],
  "paths": {
    "/v1/paye": {
      "post": {
        "summary": "Calculate paye",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "grossAnnualIncome": {
                    "type": "number"
                  },
                  "secondaryAnnualIncome": {
                    "type": "number",
                    "description": "0"
                  },
                  "annualRentPaid": {
                    "type": "number",
                    "description": "0"
                  },
                  "terminationBenefit": {
                    "type": "number",
                    "description": "0"
                  },
                  "pensionContribution": {
                    "type": "number",
                    "description": "0"
                  },
                  "nhfContribution": {
                    "type": "number",
                    "description": "0"
                  },
                  "nhisContribution": {
                    "type": "number",
                    "description": "0"
                  },
                  "lifeAssurancePremiumContribution": {
                    "type": "number",
                    "description": "0"
                  }
                },
                "required": [
                  "grossAnnualIncome"
                ]
              },
              "example": {
                "grossAnnualIncome": 6000000,
                "annualRentPaid": 1200000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "taxableIncome": 6000000,
                  "payeTax": 870000,
                  "annualTax": 870000,
                  "monthlyTax": 72500,
                  "reliefs": {
                    "rentRelief": 0,
                    "pensionRelief": 0,
                    "nhfRelief": 0,
                    "nhisRelief": 0,
                    "lifeAssurancePremiumRelief": 0,
                    "minimumWageExempt": false,
                    "taxableTerminationBenefit": 0
                  },
                  "bandBreakdown": [
                    {
                      "from": 800000,
                      "to": 3000000,
                      "rate": 0.15,
                      "taxInBand": 330000
                    },
                    {
                      "from": 3000000,
                      "to": 6000000,
                      "rate": 0.18,
                      "taxInBand": 540000
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "error": "<field> is required and must be a number"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — rate-limited at the shared Gateway level (50 req/sec, 100 burst across all endpoints)",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Always 1. Only present on the Lambda's own 429 (see description) -- Gateway's own native throttle reject, which never reaches the Lambda, has no headers at all.",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "message": "Too Many Requests"
                }
              }
            }
          }
        }
      }
    },
    "/v1/payroll/batch": {
      "post": {
        "summary": "Calculate PAYE for a batch of employees",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "employees": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 1000,
                    "items": {
                      "type": "object",
                      "properties": {
                        "grossAnnualIncome": {
                          "type": "number"
                        },
                        "secondaryAnnualIncome": {
                          "type": "number",
                          "description": "0"
                        },
                        "annualRentPaid": {
                          "type": "number",
                          "description": "0"
                        },
                        "terminationBenefit": {
                          "type": "number",
                          "description": "0"
                        },
                        "pensionContribution": {
                          "type": "number",
                          "description": "0"
                        },
                        "nhfContribution": {
                          "type": "number",
                          "description": "0"
                        },
                        "nhisContribution": {
                          "type": "number",
                          "description": "0"
                        },
                        "lifeAssurancePremiumContribution": {
                          "type": "number",
                          "description": "0"
                        }
                      },
                      "required": [
                        "grossAnnualIncome"
                      ]
                    }
                  }
                },
                "required": [
                  "employees"
                ]
              },
              "example": {
                "employees": [
                  {
                    "grossAnnualIncome": 6000000
                  },
                  {
                    "grossAnnualIncome": 900000,
                    "annualRentPaid": 400000
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "results": [
                    {
                      "taxableIncome": 6000000,
                      "payeTax": 870000,
                      "annualTax": 870000,
                      "monthlyTax": 72500,
                      "reliefs": {
                        "rentRelief": 0,
                        "pensionRelief": 0,
                        "nhfRelief": 0,
                        "nhisRelief": 0,
                        "lifeAssurancePremiumRelief": 0,
                        "minimumWageExempt": false,
                        "taxableTerminationBenefit": 0
                      },
                      "bandBreakdown": [
                        {
                          "from": 800000,
                          "to": 3000000,
                          "rate": 0.15,
                          "taxInBand": 330000
                        },
                        {
                          "from": 3000000,
                          "to": 6000000,
                          "rate": 0.18,
                          "taxInBand": 540000
                        }
                      ]
                    },
                    {
                      "taxableIncome": 820000,
                      "payeTax": 3000,
                      "annualTax": 3000,
                      "monthlyTax": 250,
                      "reliefs": {
                        "rentRelief": 80000,
                        "pensionRelief": 0,
                        "nhfRelief": 0,
                        "nhisRelief": 0,
                        "lifeAssurancePremiumRelief": 0,
                        "minimumWageExempt": false,
                        "taxableTerminationBenefit": 0
                      },
                      "bandBreakdown": [
                        {
                          "from": 800000,
                          "to": 820000,
                          "rate": 0.15,
                          "taxInBand": 3000
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "error": "employees is required and must be a non-empty array"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — rate-limited at the shared Gateway level (50 req/sec, 100 burst across all endpoints)",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Always 1. Only present on the Lambda's own 429 (see description) -- Gateway's own native throttle reject, which never reaches the Lambda, has no headers at all.",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "message": "Too Many Requests"
                }
              }
            }
          }
        }
      }
    },
    "/v1/vat": {
      "post": {
        "summary": "Calculate vat",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount": {
                    "type": "number"
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "exclusive",
                      "inclusive"
                    ]
                  },
                  "zeroRated": {
                    "type": "boolean",
                    "description": "false"
                  }
                },
                "required": [
                  "amount",
                  "mode"
                ]
              },
              "example": {
                "amount": 100000,
                "mode": "exclusive"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "net": 100000,
                  "vat": 7500,
                  "gross": 107500
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "error": "<field> is required and must be a number"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — rate-limited at the shared Gateway level (50 req/sec, 100 burst across all endpoints)",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Always 1. Only present on the Lambda's own 429 (see description) -- Gateway's own native throttle reject, which never reaches the Lambda, has no headers at all.",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "message": "Too Many Requests"
                }
              }
            }
          }
        }
      }
    },
    "/v1/presumptive": {
      "post": {
        "summary": "Calculate presumptive",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "turnover": {
                    "type": "number"
                  }
                },
                "required": [
                  "turnover"
                ]
              },
              "example": {
                "turnover": 20000000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "turnover": 20000000,
                  "taxOwed": 200000,
                  "belowFloor": false,
                  "monthlySetAside": 16666.666666666668,
                  "turnoverToFloor": 0
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "error": "<field> is required and must be a number"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — rate-limited at the shared Gateway level (50 req/sec, 100 burst across all endpoints)",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Always 1. Only present on the Lambda's own 429 (see description) -- Gateway's own native throttle reject, which never reaches the Lambda, has no headers at all.",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "message": "Too Many Requests"
                }
              }
            }
          }
        }
      }
    },
    "/v1/direct-assessment": {
      "post": {
        "summary": "Calculate direct-assessment",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "turnover": {
                    "type": "number"
                  },
                  "allowableExpenses": {
                    "type": "number"
                  },
                  "qualifyingCapitalExpenditure": {
                    "type": "number",
                    "description": "0"
                  },
                  "capitalAllowanceAssetClass": {
                    "type": "string",
                    "enum": [
                      "buildingAgriculturalMastIntangibleHeavyTransport",
                      "plantAgriculturalEquipmentFurniture",
                      "motorVehicleSoftware"
                    ],
                    "description": "\"buildingAgriculturalMastIntangibleHeavyTransport\""
                  }
                },
                "required": [
                  "turnover",
                  "allowableExpenses"
                ]
              },
              "example": {
                "turnover": 10000000,
                "allowableExpenses": 3000000,
                "qualifyingCapitalExpenditure": 1000000,
                "capitalAllowanceAssetClass": "plantAgriculturalEquipmentFurniture"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "turnover": 10000000,
                  "allowableExpenses": 3000000,
                  "capitalAllowance": 200000,
                  "taxableProfit": 6800000,
                  "taxOwed": 1014000,
                  "effectiveRate": 0.14911764705882352
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "error": "<field> is required and must be a number"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — rate-limited at the shared Gateway level (50 req/sec, 100 burst across all endpoints)",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Always 1. Only present on the Lambda's own 429 (see description) -- Gateway's own native throttle reject, which never reaches the Lambda, has no headers at all.",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "message": "Too Many Requests"
                }
              }
            }
          }
        }
      }
    },
    "/v1/cit": {
      "post": {
        "summary": "Calculate cit",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "turnover": {
                    "type": "number"
                  },
                  "fixedAssets": {
                    "type": "number"
                  },
                  "isProfessionalServices": {
                    "type": "boolean"
                  },
                  "taxableProfit": {
                    "type": "number",
                    "description": "omitted → standardRate omitted from response"
                  },
                  "assessableProfit": {
                    "type": "number",
                    "description": "omitted → developmentLevy omitted from response"
                  }
                },
                "required": [
                  "turnover",
                  "fixedAssets",
                  "isProfessionalServices"
                ]
              },
              "example": {
                "turnover": 30000000,
                "fixedAssets": 100000000,
                "isProfessionalServices": false,
                "taxableProfit": 5000000,
                "assessableProfit": 8000000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "eligibility": {
                    "turnover": 30000000,
                    "fixedAssets": 100000000,
                    "isProfessionalServices": false,
                    "turnoverEligible": true,
                    "fixedAssetsEligible": true,
                    "eligible": true,
                    "rate": 0
                  },
                  "standardRate": {
                    "taxableProfit": 5000000,
                    "annualTax": 1500000
                  },
                  "developmentLevy": {
                    "assessableProfit": 8000000,
                    "developmentLevy": 320000
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "error": "<field> is required and must be a number"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — rate-limited at the shared Gateway level (50 req/sec, 100 burst across all endpoints)",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Always 1. Only present on the Lambda's own 429 (see description) -- Gateway's own native throttle reject, which never reaches the Lambda, has no headers at all.",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "message": "Too Many Requests"
                }
              }
            }
          }
        }
      }
    },
    "/v1/wht": {
      "post": {
        "summary": "Calculate wht",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "transactionType": {
                    "type": "string",
                    "enum": [
                      "professionalFees",
                      "technicalServices",
                      "rent",
                      "generalContracts",
                      "dividends",
                      "interest",
                      "royalties"
                    ]
                  },
                  "amount": {
                    "type": "number"
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "gross",
                      "net"
                    ]
                  }
                },
                "required": [
                  "transactionType",
                  "amount",
                  "mode"
                ]
              },
              "example": {
                "transactionType": "professionalFees",
                "amount": 1000000,
                "mode": "gross"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "transactionType": "professionalFees",
                  "mode": "gross",
                  "amount": 1000000,
                  "rate": 0.05,
                  "gross": 1000000,
                  "withheld": 50000,
                  "net": 950000
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "error": "<field> is required and must be a number"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — rate-limited at the shared Gateway level (50 req/sec, 100 burst across all endpoints)",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Always 1. Only present on the Lambda's own 429 (see description) -- Gateway's own native throttle reject, which never reaches the Lambda, has no headers at all.",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "message": "Too Many Requests"
                }
              }
            }
          }
        }
      }
    },
    "/v1/employer-cost": {
      "post": {
        "summary": "Calculate employer-cost",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "annualBasicSalary": {
                    "type": "number"
                  },
                  "annualHousingAllowance": {
                    "type": "number",
                    "description": "0"
                  },
                  "annualTransportAllowance": {
                    "type": "number",
                    "description": "0"
                  },
                  "annualOtherAllowances": {
                    "type": "number",
                    "description": "0"
                  },
                  "annualRentPaid": {
                    "type": "number",
                    "description": "0"
                  }
                },
                "required": [
                  "annualBasicSalary"
                ]
              },
              "example": {
                "annualBasicSalary": 6000000,
                "annualHousingAllowance": 1000000,
                "annualTransportAllowance": 500000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "annualGrossPay": 7500000,
                  "pensionablePay": 7500000,
                  "employerPensionContribution": 750000,
                  "employerNhisContribution": 600000,
                  "employerNsitfContribution": 75000,
                  "employerItfContribution": 75000,
                  "totalStatutoryEmployerCost": 9000000,
                  "employeePaye": {
                    "taxableIncome": 6600000,
                    "payeTax": 978000,
                    "annualTax": 978000,
                    "monthlyTax": 81500,
                    "reliefs": {
                      "rentRelief": 0,
                      "pensionRelief": 600000,
                      "nhfRelief": 0,
                      "nhisRelief": 300000,
                      "lifeAssurancePremiumRelief": 0,
                      "minimumWageExempt": false,
                      "taxableTerminationBenefit": 0
                    },
                    "bandBreakdown": [
                      {
                        "from": 800000,
                        "to": 3000000,
                        "rate": 0.15,
                        "taxInBand": 330000
                      },
                      {
                        "from": 3000000,
                        "to": 6600000,
                        "rate": 0.18,
                        "taxInBand": 648000
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "error": "<field> is required and must be a number"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — rate-limited at the shared Gateway level (50 req/sec, 100 burst across all endpoints)",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Always 1. Only present on the Lambda's own 429 (see description) -- Gateway's own native throttle reject, which never reaches the Lambda, has no headers at all.",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "message": "Too Many Requests"
                }
              }
            }
          }
        }
      }
    },
    "/v1/cgt": {
      "post": {
        "summary": "Calculate cgt",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "taxpayerType": {
                    "type": "string",
                    "enum": [
                      "individual",
                      "company"
                    ]
                  },
                  "assetType": {
                    "type": "string",
                    "enum": [
                      "property",
                      "shares",
                      "digital-asset",
                      "other"
                    ]
                  },
                  "disposalProceeds": {
                    "type": "number"
                  },
                  "costBase": {
                    "type": "number"
                  },
                  "isPrincipalPrivateResidence": {
                    "type": "boolean",
                    "description": "false (property only)"
                  },
                  "isFullyReinvestedInNigerianShares": {
                    "type": "boolean",
                    "description": "false (shares only)"
                  },
                  "isRegulatedSecuritiesLendingTransfer": {
                    "type": "boolean",
                    "description": "false (shares only)"
                  },
                  "digitalAssetCategory": {
                    "type": "string",
                    "enum": [
                      "crypto",
                      "stablecoin",
                      "security-token",
                      "utility-token",
                      "nft",
                      "sovereign-digital-currency"
                    ],
                    "description": "required when assetType is \"digital-asset\", ignored otherwise"
                  },
                  "otherAnnualTaxableIncome": {
                    "type": "number",
                    "description": "0 (individual only)"
                  },
                  "isSmallCompany": {
                    "type": "boolean",
                    "description": "false (company only)"
                  }
                },
                "required": [
                  "taxpayerType",
                  "assetType",
                  "disposalProceeds",
                  "costBase"
                ]
              },
              "example": {
                "taxpayerType": "individual",
                "assetType": "property",
                "disposalProceeds": 50000000,
                "costBase": 30000000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "chargeableGain": 20000000,
                  "exempt": false,
                  "cgtLiability": 3630000
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "error": "<field> is required and must be a number"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — rate-limited at the shared Gateway level (50 req/sec, 100 burst across all endpoints)",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Always 1. Only present on the Lambda's own 429 (see description) -- Gateway's own native throttle reject, which never reaches the Lambda, has no headers at all.",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "message": "Too Many Requests"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stamp-duty": {
      "post": {
        "summary": "Calculate stamp-duty",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "instrumentType": {
                    "type": "string",
                    "enum": [
                      "tenancy",
                      "propertyConveyance",
                      "shareCapital",
                      "loanCapital",
                      "marketableSecurities",
                      "electronicTransfer",
                      "other"
                    ]
                  },
                  "amount": {
                    "type": "number"
                  }
                },
                "required": [
                  "instrumentType",
                  "amount"
                ]
              },
              "example": {
                "instrumentType": "tenancy",
                "amount": 12000000
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "instrumentType": "tenancy",
                  "amount": 12000000,
                  "rate": 0.0078,
                  "duty": 93600,
                  "exempt": false
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "error": "<field> is required and must be a number"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — rate-limited at the shared Gateway level (50 req/sec, 100 burst across all endpoints)",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Always 1. Only present on the Lambda's own 429 (see description) -- Gateway's own native throttle reject, which never reaches the Lambda, has no headers at all.",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "message": "Too Many Requests"
                }
              }
            }
          }
        }
      }
    },
    "/v1/import-duty": {
      "post": {
        "summary": "Calculate import-duty",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fob": {
                    "type": "number"
                  },
                  "freight": {
                    "type": "number",
                    "description": "0"
                  },
                  "insurance": {
                    "type": "number",
                    "description": "0"
                  },
                  "band": {
                    "type": "string",
                    "enum": [
                      "0",
                      "5",
                      "10",
                      "20",
                      "35"
                    ]
                  },
                  "customDutyRatePercent": {
                    "type": "number",
                    "description": "omitted → band rate applies"
                  }
                },
                "required": [
                  "fob",
                  "band"
                ]
              },
              "example": {
                "fob": 5000000,
                "freight": 300000,
                "insurance": 100000,
                "band": "20"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful calculation",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "fob": 5000000,
                  "freight": 300000,
                  "insurance": 100000,
                  "cif": 5400000,
                  "band": "20",
                  "dutyRate": 0.2,
                  "duty": 1080000,
                  "surcharge": 75600,
                  "etls": 27000,
                  "fcs": 200000,
                  "vat": 508695,
                  "totalLandedCost": 7291295
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid field",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "error": "<field> is required and must be a number"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests — rate-limited at the shared Gateway level (50 req/sec, 100 burst across all endpoints)",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "The shared per-second request ceiling. Constant (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests remaining in the current one-second window, across all callers (not per-caller).",
                "schema": {
                  "type": "integer",
                  "example": 49
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) when the current window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1757746042
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Always 1. Only present on the Lambda's own 429 (see description) -- Gateway's own native throttle reject, which never reaches the Lambda, has no headers at all.",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            },
            "content": {
              "application/json": {
                "example": {
                  "message": "Too Many Requests"
                }
              }
            }
          }
        }
      }
    }
  }
}