{
  "openapi": "3.1.0",
  "info": {
    "title": "Herramientas inmobiliarias publicas de Felix Lopez",
    "version": "1.0.0",
    "description": "Calculos orientativos y datos oficiales para preparar la venta de una vivienda en Tenerife. Los resultados no sustituyen una tasacion, una liquidacion fiscal ni asesoramiento juridico."
  },
  "servers": [
    {
      "url": "https://felixlopez.es",
      "description": "Produccion"
    }
  ],
  "paths": {
    "/api/tools/market/": {
      "get": {
        "operationId": "getTenerifeNorthMarketIndicator",
        "summary": "Consultar indicadores oficiales por municipio",
        "description": "Devuelve compraventas y valor tasado oficial con periodo y fuentes. No equivale a una valoracion individual.",
        "parameters": [
          {
            "name": "municipality",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": ["la-laguna", "tacoronte", "el-rosario", "puerto-de-la-cruz"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Indicador encontrado",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PublicResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/tools/sale-costs/": {
      "post": {
        "operationId": "estimateSaleNet",
        "summary": "Estimar el neto de una venta",
        "description": "Separa gastos de transmision, deuda hipotecaria, ganancia patrimonial estimada, IRPF y neto orientativo.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SaleInput" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Estimacion calculada",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PublicResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "413": { "$ref": "#/components/responses/TooLarge" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/tools/plusvalia/": {
      "post": {
        "operationId": "estimateMunicipalPlusvalia",
        "summary": "Estimar la plusvalia municipal",
        "description": "Compara la base objetiva y el incremento real del IIVTNU. La ordenanza municipal puede modificar el resultado final.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/PlusvaliaInput" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Estimacion calculada",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PublicResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "413": { "$ref": "#/components/responses/TooLarge" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/api/tools/documents/": {
      "post": {
        "operationId": "getSellerDocumentChecklist",
        "summary": "Preparar una lista de documentos para vender",
        "description": "Genera una lista segun exista hipoteca, herencia, alquiler, comunidad de propietarios o una persona vendedora no residente.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/DocumentsInput" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Lista preparada",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PublicResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidInput" },
          "413": { "$ref": "#/components/responses/TooLarge" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "PublicResponse": {
        "type": "object",
        "required": ["data", "meta"],
        "properties": {
          "data": { "type": "object", "additionalProperties": true },
          "meta": { "type": "object", "additionalProperties": true }
        }
      },
      "SaleInput": {
        "type": "object",
        "required": ["salePrice", "purchasePrice"],
        "properties": {
          "salePrice": { "type": "number", "exclusiveMinimum": 0 },
          "purchasePrice": { "type": "number", "minimum": 0 },
          "purchaseExpenses": { "type": "number", "minimum": 0, "default": 0 },
          "improvements": { "type": "number", "minimum": 0, "default": 0 },
          "deductibleAmortization": { "type": "number", "minimum": 0, "default": 0 },
          "additionalSaleExpenses": { "type": "number", "minimum": 0, "default": 0 },
          "agencyFeePercent": { "type": "number", "minimum": 0, "maximum": 15, "default": 0 },
          "municipalPlusvalia": { "type": "number", "minimum": 0, "default": 0 },
          "outstandingMortgagePrincipal": { "type": "number", "minimum": 0, "default": 0 },
          "mortgageCancellationCost": { "type": "number", "minimum": 0, "default": 0 },
          "energyCertificateCost": { "type": "number", "minimum": 0, "default": 0 },
          "exemptionType": { "type": "string", "enum": ["none", "reinvestment", "over65-habitual"], "default": "none" },
          "reinvestmentAmount": { "type": "number", "minimum": 0, "default": 0 }
        }
      },
      "PlusvaliaInput": {
        "type": "object",
        "required": ["acquisitionDate", "transferDate", "acquisitionPrice", "transferPrice", "cadastralTotalValue", "cadastralLandValue", "municipalTaxRate"],
        "properties": {
          "acquisitionDate": { "type": "string", "format": "date" },
          "transferDate": { "type": "string", "format": "date" },
          "acquisitionPrice": { "type": "number", "minimum": 0 },
          "transferPrice": { "type": "number", "minimum": 0 },
          "cadastralTotalValue": { "type": "number", "exclusiveMinimum": 0 },
          "cadastralLandValue": { "type": "number", "exclusiveMinimum": 0 },
          "municipalTaxRate": { "type": "number", "minimum": 0, "maximum": 30 }
        }
      },
      "DocumentsInput": {
        "type": "object",
        "properties": {
          "hasMortgage": { "type": "boolean", "default": false },
          "isInherited": { "type": "boolean", "default": false },
          "isRented": { "type": "boolean", "default": false },
          "isCommunityProperty": { "type": "boolean", "default": false },
          "hasForeignOwner": { "type": "boolean", "default": false }
        }
      }
    },
    "responses": {
      "InvalidInput": { "description": "Entrada no valida" },
      "TooLarge": { "description": "Solicitud demasiado grande" },
      "RateLimited": { "description": "Demasiadas solicitudes" }
    }
  }
}
