{
  "openapi": "3.1.0",
  "info": {
    "title": "API publica de Castro Mudanzas",
    "version": "1.0.0",
    "summary": "Consultar tarifas y crear una solicitud de mudanza.",
    "description": "API publica de Castro Mudanzas, empresa de mudanzas y fletes en Barcelona y Cataluna. Permite consultar las tarifas vigentes y registrar una solicitud de mudanza sin autenticacion.\n\nUna solicitud NO es una reserva confirmada: alguien de Castro llama para confirmar fecha, direccion y precio final. Cada solicitud genera un aviso a una persona real, asi que no debe usarse para pruebas masivas.\n\nContexto en lenguaje natural: https://castromudanzas.es/llms.txt",
    "contact": {
      "name": "Castro Mudanzas",
      "url": "https://castromudanzas.es/contacto/",
      "email": "ventas@castromudanzas.es"
    }
  },
  "servers": [
    {
      "url": "https://api.castromudanzas.es",
      "description": "Produccion"
    }
  ],
  "paths": {
    "/api/precios": {
      "get": {
        "operationId": "obtenerTarifas",
        "summary": "Tarifas vigentes",
        "description": "Devuelve las tarifas con las que se calcula cualquier presupuesto: precio por hora de cada vehiculo, minimo de horas contratadas, precio por ayudante, precio por kilometro y radio de kilometros incluidos sin coste.\n\nFormula del presupuesto:\n  total = precio_hora_vehiculo * max(horas, minimo_horas)\n        + precio_hora_ayudante * ayudantes * max(horas, minimo_horas)\n        + precio_km * max(0, km_totales - km_gratis)",
        "responses": {
          "200": {
            "description": "Tarifas vigentes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RespuestaPrecios"
                },
                "example": {
                  "ok": true,
                  "precios": {
                    "precio_hora_furgoneta": 40,
                    "precio_hora_furgon": 50,
                    "precio_hora_camion": 70,
                    "precio_hora_camion_plataforma": 80,
                    "minimo_horas": 2,
                    "precio_hora_ayudante": 20,
                    "precio_km": 1.2,
                    "km_gratis": 10
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/inventario": {
      "get": {
        "operationId": "listarInventario",
        "summary": "Catalogo de objetos para calcular volumen",
        "description": "Objetos tipicos de una mudanza agrupados por estancia, con su peso y volumen estimados. Sirve para deducir que vehiculo hace falta.",
        "responses": {
          "200": {
            "description": "Listado de objetos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/leads": {
      "post": {
        "operationId": "crearSolicitudMudanza",
        "summary": "Crear una solicitud de mudanza",
        "description": "Registra una solicitud de mudanza y avisa al equipo de Castro. El unico campo obligatorio es el telefono; cuantos mas datos se envien, mas cerrado sale el presupuesto y menos llamadas hacen falta.\n\nDevuelve 201 con el identificador de la solicitud. El precio final NO se devuelve aqui: lo confirma una persona por telefono.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SolicitudMudanza"
              },
              "example": {
                "telefono": "+34600111222",
                "nombre": "Marta Ruiz",
                "email": "marta@example.com",
                "origen": "Carrer Bruc 8, 4o sin ascensor, Santa Coloma de Gramenet",
                "destino": "Carrer Girona 120, 2o con ascensor, Barcelona",
                "vehiculo_nombre": "Furgoneta",
                "ayudantes": 1,
                "carga_descarga": true,
                "fecha_mudanza": "2026-10-14",
                "hora_mudanza": "09:00",
                "comentarios": "Piso de 2 habitaciones. Hay una lavadora y un sofa de 3 plazas."
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Solicitud registrada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "lead_id": {
                      "type": "integer",
                      "description": "Identificador de la solicitud."
                    }
                  },
                  "required": [
                    "ok",
                    "lead_id"
                  ]
                },
                "example": {
                  "ok": true,
                  "lead_id": 184
                }
              }
            }
          },
          "400": {
            "description": "Faltan datos o el telefono no es valido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": "Telefono requerido (minimo 9 digitos)."
                }
              }
            }
          },
          "429": {
            "description": "Demasiadas peticiones. Espera antes de reintentar."
          },
          "500": {
            "description": "Error del servidor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "SolicitudMudanza": {
        "type": "object",
        "required": [
          "telefono"
        ],
        "properties": {
          "telefono": {
            "type": "string",
            "minLength": 9,
            "description": "Telefono de contacto. Minimo 9 digitos. Es el unico campo obligatorio.",
            "examples": [
              "+34600111222"
            ]
          },
          "nombre": {
            "type": "string",
            "description": "Nombre de quien contrata."
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "origen": {
            "type": "string",
            "description": "Direccion de origen. Incluir piso y si hay ascensor cambia mucho el presupuesto."
          },
          "destino": {
            "type": "string",
            "description": "Direccion de destino, con piso y ascensor."
          },
          "vehiculo_nombre": {
            "type": "string",
            "enum": [
              "Furgoneta",
              "Furgon",
              "Camion",
              "Camion con plataforma"
            ],
            "description": "Si no se sabe, dejarlo vacio y lo decide Castro segun el volumen."
          },
          "ayudantes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 6,
            "description": "Ayudantes ademas del conductor."
          },
          "carga_descarga": {
            "type": "boolean",
            "description": "Si Castro se encarga de subir y bajar los bultos."
          },
          "fecha_mudanza": {
            "type": "string",
            "format": "date",
            "examples": [
              "2026-10-14"
            ]
          },
          "hora_mudanza": {
            "type": "string",
            "pattern": "^[0-2][0-9]:[0-5][0-9]$",
            "description": "Hora deseada, horario de atencion 08:00-18:00.",
            "examples": [
              "09:00"
            ]
          },
          "comentarios": {
            "type": "string",
            "description": "Todo lo que ayude a dimensionar: habitaciones, muebles grandes, electrodomesticos, calle estrecha, permiso de aparcamiento."
          }
        }
      },
      "RespuestaPrecios": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "precios": {
            "type": "object",
            "properties": {
              "precio_hora_furgoneta": {
                "type": "number",
                "description": "EUR por hora."
              },
              "precio_hora_furgon": {
                "type": "number"
              },
              "precio_hora_camion": {
                "type": "number"
              },
              "precio_hora_camion_plataforma": {
                "type": "number"
              },
              "minimo_horas": {
                "type": "number",
                "description": "Horas minimas facturables."
              },
              "precio_hora_ayudante": {
                "type": "number"
              },
              "precio_km": {
                "type": "number",
                "description": "EUR por km fuera del radio incluido."
              },
              "km_gratis": {
                "type": "number",
                "description": "Km incluidos sin coste."
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string"
          }
        }
      }
    }
  }
}
