{"name":"Observatorio de Vivienda de España — API de lectura","version":"1.0.0","what_is_this":"Base de datos de vivienda en España (MVP: España, Madrid, Barcelona, Málaga, València, Cantabria/Santander y Zamora a nivel de municipio, provincia y comunidad autónoma) en la que CADA número puede responder quién lo publicó, de qué URL salió, qué periodo representa, cuándo se publicó y se ingirió, con qué metodología, si es observación, estimación o cálculo derivado, sus limitaciones y su confianza. Esta API sólo lee: no inventa, no interpola y no rellena huecos.","principles":["Toda cifra viaja en una tarjeta con periodo de referencia, fuente (publicador + dataset), naturaleza (observed/estimated/derived), confianza A-F, estado de publicación y enlace de traza hasta el fichero raw. Cítala siempre con esos datos.","Nunca se inventan ni rellenan valores: si una métrica no existe para un territorio, la respuesta lo dice (data_gaps, 404 no_data) y, como mucho, ofrece el dato del nivel superior etiquetado como de OTRO territorio.","Nunca se elige en silencio entre fuentes: /latest da la fuente principal con la regla usada (selection) y TODAS las alternativas.","Series de distinta versión metodológica (methodology_version) son series distintas: nunca se empalman ni se calcula una variación entre ellas (ver methodology_breaks).","Un concepto = una métrica; actos distintos = métricas distintas (compraventa inscrita ≠ firmada; certificado de fin de obra ≠ estimación de terminadas; calificación de protegida ≠ obra).","Las categorías no se convierten: vivienda no principal ≠ vacía; 'a disposición del titular' (AEAT) ≠ vacía; sociedad ≠ fondo; gran tenedor ≠ especulador; brecha hogares−terminadas ≠ familias sin vivienda.","La confianza F nunca entra en /latest ni en derivados. Los derivados llevan fórmula versionada y linaje exacto (inputs).","Toda advertencia (warnings) se devuelve; el consumidor decide cómo mostrarla, nunca si omitirla."],"confidence_classes":{"A":"A: dato administrativo u observación directa de fuente oficial","B":"B: estimación oficial (método publicado por la fuente)","C":"C: derivado reproducible del observatorio (fórmula versionada, entradas trazables)","D":"D: investigación no oficial","E":"E: proxy (mide otra cosa que se usa como aproximación)","F":"F: no verificable; nunca entra en /latest ni en derivados"},"value_natures":{"observed":"observed: recuento u observación directa publicada por la fuente","estimated":"estimated: estimación oficial de la fuente (encuesta, modelo, interpolación declarada)","derived":"derived: calculado por el observatorio a partir de otras observaciones (ver fórmula y linaje en la traza)"},"period_types":{"point":"point: stock a una fecha (p.ej. parque a 1 de enero)","month":"month: flujo mensual","quarter":"quarter: flujo trimestral","semester":"semester: flujo semestral","year":"year: flujo anual (año natural)","rolling_12m":"rolling_12m: acumulado móvil de 12 meses / 4 trimestres (no es un año natural)","multi_year":"multi_year: ventana de varios años (p.ej. 2021-2025)"},"publication_status":{"provisional":"provisional: la fuente lo marca como provisional (puede revisarse)","definitive":"definitive: la fuente lo da por definitivo","unknown":"unknown: la fuente no informa del estado"},"warning_codes":{"old_data":"El dato tiene más de 5 años de antigüedad.","estimate":"Estimación oficial, no observación directa.","derived":"Indicador calculado por el observatorio (ver fórmula y advertencias en la traza).","derived_definition_warning":"Lo que el indicador derivado NO significa, según su fórmula versionada (p.ej. sociedad ≠ fondo).","provisional":"Dato provisional según la fuente.","low_confidence":"Confianza D o E.","multiple_sources":"Hay otras fuentes con otra cifra para la misma métrica y territorio (ver alternatives).","periods_differ":"Los periodos comparados no coinciden.","mixed_sources":"Los territorios comparados usan fuentes distintas.","mixed_methodology":"Los territorios comparados usan versiones metodológicas distintas.","no_data":"Sin dato para ese territorio (no se rellena).","geo_substituted":"El dato mostrado es de OTRO territorio (nivel superior), etiquetado como tal.","<caveat code>":"Cualquier otro código es una advertencia declarada en el catálogo (GET /v1/caveats)."},"geo_code_formats":{"ES":"España (país).","CAnn":"Comunidad autónoma por código INE de 2 dígitos: CA13 Madrid, CA09 Cataluña, CA01 Andalucía, CA10 C. Valenciana, CA06 Cantabria, CA07 Castilla y León.","PRnn":"Provincia por código INE de 2 dígitos: PR28 Madrid, PR08 Barcelona, PR29 Málaga, PR46 Valencia, PR39 Cantabria, PR49 Zamora.","MUnnnnn":"Municipio por código INE de 5 dígitos: MU28079 Madrid, MU08019 Barcelona, MU29067 Málaga, MU46250 València, MU39075 Santander, MU49275 Zamora."},"category_caveats":["vivienda no principal ≠ vivienda vacía (el Censo 2021 deriva 'vacía' del consumo eléctrico; 'no principal' incluye segundas residencias).","'a disposición del titular' (AEAT, IRPF) ≠ vivienda vacía: es una categoría fiscal residual (ni habitual ni arrendada).","sociedad (persona jurídica titular catastral) ≠ fondo de inversión; titular con más de 10 inmuebles en un ámbito ≠ gran tenedor legal.","gran tenedor ≠ especulador: ninguna métrica etiqueta intenciones.","brecha hogares nuevos − viviendas terminadas ≠ familias sin vivienda ni viviendas que faltan.","compraventas inscritas (Registro, INE ETDP) ≠ compraventas firmadas (notarios, MIVAU): actos y fechas distintos.","viviendas terminadas (estimación MIVAU desde visados) ≠ certificados de fin de obra (CGATE, observado).","vivienda turística medida por INE (anuncios en plataformas) ≠ registrada en un registro autonómico (licencias): no se suman.","índice de precios (evolución, base 100) ≠ nivel de precios (€/m²); precio registral ≠ valor tasado ≠ alquiler declarado."],"workflow":[{"step":1,"action":"Mira qué existe antes de preguntar: la matriz métrica × nivel con el último periodo de cada celda.","endpoint":"GET /v1/coverage  (o GET /v1/coverage?geo=PR28 para un territorio)","why":"Muchas métricas no existen a nivel municipal (p.ej. el parque MIVAU llega a provincia). Evita pedir lo que no hay."},{"step":2,"action":"Resuelve el territorio a un código canónico y elige el nivel.","endpoint":"GET /v1/geographies?q=Madrid  →  MU28079 (municipio), PR28 (provincia), CA13 (comunidad)","why":"Un mismo nombre existe a varios niveles. Sólo las zonas del MVP (GET /v1/zones) tienen datos."},{"step":3,"action":"Encuentra la métrica y lee su ficha: definición, fuentes, advertencias (lo que NO significa), rupturas y cobertura.","endpoint":"GET /v1/metrics?q=vacía  →  GET /v1/metrics/vacant_housing","why":"La ficha trae los caveats críticos (p.ej. vacía ≠ no principal) y peticiones de ejemplo con códigos reales."},{"step":4,"action":"Pide el último dato. Lee selection (por qué esa fuente), alternatives (otras fuentes) y warnings (antigüedad, estimación...).","endpoint":"GET /v1/latest/total_housing_stock/PR28   (añade ?period_type=year si hay flujos mensuales y anuales)","why":"Una métrica puede tener varias fuentes con cifras distintas; nunca se elige en silencio."},{"step":5,"action":"Para la evolución, pide la serie: una serie por fuente y versión metodológica.","endpoint":"GET /v1/observations?metric=sales_registered&geo=PR08&from=2024-01-01","why":"Dos series consecutivas con methodology_version distinta NO se empalman."},{"step":6,"action":"Para comparar territorios, usa /compare y respeta alignment y warnings.","endpoint":"GET /v1/compare?metric=vacancy_ratio&zones=mvp&level=province","why":"Si alignment=latest_per_geo los periodos difieren y la comparación directa no vale. zones=mvp compara los territorios del MVP de UN nivel: level=province da 6 provincias (Cantabria y Santander comparten PR39; España sólo existe a nivel country), level=municipality da 6 municipios (la zona Cantabria no tiene municipio). Si ninguno tiene dato (alignment=no_data), el aviso no_data dice en qué nivel sí lo hay."},{"step":7,"action":"Para una visión completa de un lugar, pide el perfil (o la evidencia por dimensiones de una afirmación).","endpoint":"GET /v1/housing-profile/MU28079   |   GET /v1/claims/evidence?geo=MU28079&dimensions=supply_constraint,price_pressure","why":"Traen huecos explícitos (data_gaps) con el nivel superior más cercano etiquetado como otro territorio, y el dato más antiguo."},{"step":8,"action":"Si hace falta, verifica la cifra hasta el fichero original.","endpoint":"GET /v1/observations/{observation_id}  →  raw_file.content_url descarga los bytes; compara el sha256","why":"La traza llega a la celda/línea exacta (raw.record_reference). En derivados, inputs trae la traza de cada entrada."},{"step":9,"action":"Al responder, cita: valor + unidad, periodo (label), fuente (publisher, dataset), naturaleza, confianza y trace_url. Si usaste un territorio superior o un dato antiguo, dilo.","endpoint":"(campos de la tarjeta)","why":"Es la regla del observatorio: ninguna cifra sin su procedencia."},{"step":10,"action":"Si no hay dato, no estimes ni rellenes: di que no existe a ese nivel y qué niveles sí lo tienen.","endpoint":"error.suggestions del 404 no_data  |  data_gaps del perfil","why":"Rellenar o interpolar está prohibido por diseño."}],"endpoint_index":[{"method":"GET","path":"/v1","summary":"Guía para agentes: qué es esta API, principios, leyendas A-F, flujo para responder preguntas e índice de endpoints","tags":["guía"]},{"method":"GET","path":"/v1/agent-guide.md","summary":"La guía para agentes en Markdown (misma fuente que GET /v1)","tags":["guía"]},{"method":"GET","path":"/llms.txt","summary":"llms.txt: la guía para agentes en texto (convención llms.txt)","tags":["guía"]},{"method":"GET","path":"/v1/geographies","summary":"Busca territorios (España, CCAA, provincias, municipios) y devuelve sus códigos","tags":["descubrimiento"]},{"method":"GET","path":"/v1/geographies/{code}","summary":"Un territorio: jerarquía, zonas del MVP y métricas con datos (con su último periodo)","tags":["descubrimiento"]},{"method":"GET","path":"/v1/zones","summary":"Zonas del MVP: los territorios que tienen datos cargados","tags":["descubrimiento"]},{"method":"GET","path":"/v1/panels","summary":"Paneles del dashboard declarados en el catálogo (qué métricas van juntas y con qué period_type)","tags":["descubrimiento","dashboard"]},{"method":"GET","path":"/v1/metrics","summary":"Catálogo de métricas con resumen de cobertura (niveles, territorios, último periodo, fuentes)","tags":["descubrimiento"]},{"method":"GET","path":"/v1/metrics/{code}","summary":"Todo sobre una métrica: definición, fuentes, advertencias, rupturas, discrepancias, fórmula y cobertura","tags":["descubrimiento"]},{"method":"GET","path":"/v1/sources","summary":"Catálogo de fuentes (datasets oficiales) con las métricas que alimentan","tags":["descubrimiento"]},{"method":"GET","path":"/v1/sources/{code}","summary":"Todo sobre una fuente: metadatos, licencia, limitaciones, métricas, raws e ingestas","tags":["descubrimiento"]},{"method":"GET","path":"/v1/coverage","summary":"Qué se puede preguntar: matriz métrica × nivel con último periodo, territorios, fuentes y confianza","tags":["descubrimiento"]},{"method":"GET","path":"/v1/caveats","summary":"Advertencias del catálogo (lo que un dato NO significa), filtrables por métrica, fuente, territorio y severidad","tags":["descubrimiento"]},{"method":"GET","path":"/v1/discrepancies","summary":"Cifras de fuentes distintas que no cuadran, documentadas (qué mide cada una y cómo se trata)","tags":["descubrimiento"]},{"method":"GET","path":"/v1/methodology-breaks","summary":"Rupturas metodológicas declaradas: dónde una serie cambia de versión y deja de ser comparable","tags":["descubrimiento"]},{"method":"GET","path":"/v1/observations","summary":"Series vigentes de una o varias métricas en uno o varios territorios, agrupadas por fuente y versión metodológica","tags":["datos"]},{"method":"GET","path":"/v1/observations/{obs_id}","summary":"Traza completa de una observación: métrica → fuente → fichero raw → celda de origen → entradas si es derivada","tags":["datos"]},{"method":"GET","path":"/v1/trace/{obs_id}","summary":"Alias de GET /v1/observations/{obs_id} (traza completa)","tags":["datos"]},{"method":"GET","path":"/v1/latest","summary":"Último dato de varias métricas × territorios en una llamada (sin error si alguna pareja no tiene dato)","tags":["datos"]},{"method":"GET","path":"/v1/latest/{metric}/{geo}","summary":"Último dato de una métrica en un territorio, con la fuente principal explicada y las alternativas","tags":["datos"]},{"method":"GET","path":"/v1/compare","summary":"Compara una métrica entre territorios alineando el periodo (y avisando cuando no se puede)","tags":["datos"]},{"method":"GET","path":"/v1/housing-profile/{geo}","summary":"Perfil de vivienda de un territorio: último dato de cada métrica del catálogo, por secciones, con huecos explícitos","tags":["datos"]},{"method":"GET","path":"/v1/changes","summary":"Qué ha cambiado desde una fecha: observaciones nuevas y revisiones por métrica y fuente, e ingestas","tags":["datos"]},{"method":"GET","path":"/v1/export","summary":"Exporta observaciones vigentes a CSV con columnas de procedencia (fuente, periodo, confianza, raw, traza)","tags":["datos"]},{"method":"GET","path":"/v1/table","summary":"Tabla de una métrica: último dato por territorio de un nivel, con su comunidad para agrupar","tags":["datos"]},{"method":"GET","path":"/v1/territory-table/{geo}","summary":"Tabla de un territorio: último dato de cada métrica con datos (fuente principal, periodo, confianza, tema)","tags":["datos"]},{"method":"GET","path":"/v1/territories","summary":"Territorios con datos cargados, con su comunidad y provincia (para selectores)","tags":["datos"]},{"method":"GET","path":"/v1/claims/dimensions","summary":"Dimensiones medibles del análisis de afirmaciones, con sus métricas y lo que NO significan","tags":["afirmaciones"]},{"method":"GET","path":"/v1/claims/evidence","summary":"Paquete de evidencia por dimensiones para un territorio: tarjetas, fechas, dato crítico más antiguo, huecos y advertencias","tags":["afirmaciones"]},{"method":"GET","path":"/v1/legal/norms","summary":"Normas de vivienda cargadas del BOE con el estado de la norma completa (vigente, derogada, anulada...)","tags":["legal"]},{"method":"GET","path":"/v1/legal/norms/{norm_id}","summary":"Una norma: estado vigente, historial de lecturas del BOE (con raw), relaciones tipadas y medidas que la usan","tags":["legal"]},{"method":"GET","path":"/v1/legal/measures","summary":"Medidas de política de vivienda (curadas) con su estado jurídico EN una fecha, filtrables por territorio","tags":["legal"]},{"method":"GET","path":"/v1/quality","summary":"Resultados de los controles de calidad (por defecto sólo los fallidos)","tags":["operación"]},{"method":"GET","path":"/v1/ingestion-runs","summary":"Ejecuciones de los conectores (estado, estadísticas, errores)","tags":["operación"]},{"method":"GET","path":"/v1/raw-files/{raw_id}","summary":"Metadatos de un fichero raw (URL original, sha256, tamaño, cabeceras, versión anterior)","tags":["operación"]},{"method":"GET","path":"/v1/raw-files/{raw_id}/content","summary":"Descarga los bytes originales de un fichero raw","tags":["operación"]}],"mvp_zones":[{"id":"espana","label":"España","geos":[{"code":"ES","name":"España","level":"country","ine_code":"00"}]},{"id":"madrid","label":"Madrid","geos":[{"code":"MU28079","name":"Madrid","level":"municipality","ine_code":"28079"},{"code":"PR28","name":"Madrid","level":"province","ine_code":"28"},{"code":"CA13","name":"Madrid, Comunidad de","level":"autonomous_community","ine_code":"13"}]},{"id":"barcelona","label":"Barcelona","geos":[{"code":"MU08019","name":"Barcelona","level":"municipality","ine_code":"08019"},{"code":"PR08","name":"Barcelona","level":"province","ine_code":"08"},{"code":"CA09","name":"Cataluña","level":"autonomous_community","ine_code":"09"}]},{"id":"malaga","label":"Málaga","geos":[{"code":"MU29067","name":"Málaga","level":"municipality","ine_code":"29067"},{"code":"PR29","name":"Málaga","level":"province","ine_code":"29"},{"code":"CA01","name":"Andalucía","level":"autonomous_community","ine_code":"01"}]},{"id":"valencia","label":"València","geos":[{"code":"MU46250","name":"València","level":"municipality","ine_code":"46250"},{"code":"PR46","name":"Valencia/València","level":"province","ine_code":"46"},{"code":"CA10","name":"Comunitat Valenciana","level":"autonomous_community","ine_code":"10"}]},{"id":"cantabria","label":"Cantabria","geos":[{"code":"PR39","name":"Cantabria","level":"province","ine_code":"39"},{"code":"CA06","name":"Cantabria","level":"autonomous_community","ine_code":"06"}]},{"id":"santander","label":"Santander","geos":[{"code":"MU39075","name":"Santander","level":"municipality","ine_code":"39075"},{"code":"PR39","name":"Cantabria","level":"province","ine_code":"39"}]},{"id":"zamora","label":"Zamora","geos":[{"code":"MU49275","name":"Zamora","level":"municipality","ine_code":"49275"},{"code":"PR49","name":"Zamora","level":"province","ine_code":"49"},{"code":"CA07","name":"Castilla y León","level":"autonomous_community","ine_code":"07"}]}],"examples":[{"title":"Qué hay para la provincia de Madrid (cobertura por métrica)","url":"/v1/coverage?geo=PR28","curl":"curl -s 'http://127.0.0.1:8765/v1/coverage?geo=PR28'"},{"title":"Códigos de todo lo que se llama Madrid","url":"/v1/geographies?q=Madrid","curl":"curl -s 'http://127.0.0.1:8765/v1/geographies?q=Madrid'"},{"title":"Ficha de la métrica vivienda vacía (caveats, fuentes, cobertura)","url":"/v1/metrics/vacant_housing","curl":"curl -s 'http://127.0.0.1:8765/v1/metrics/vacant_housing'"},{"title":"Último parque de viviendas de la provincia de Madrid, con alternativas (Censo 2021 vs MIVAU)","url":"/v1/latest/total_housing_stock/PR28","curl":"curl -s 'http://127.0.0.1:8765/v1/latest/total_housing_stock/PR28'"},{"title":"Última tasa de vivienda vacía (derivado) en el municipio de Madrid","url":"/v1/latest/vacancy_ratio/MU28079","curl":"curl -s 'http://127.0.0.1:8765/v1/latest/vacancy_ratio/MU28079'"},{"title":"Viviendas terminadas: último AÑO completo (no el último mes) en Madrid provincia","url":"/v1/latest/completed_housing/PR28?period_type=year","curl":"curl -s 'http://127.0.0.1:8765/v1/latest/completed_housing/PR28?period_type=year'"},{"title":"Varios últimos datos de una vez","url":"/v1/latest?metric=population&metric=households&geo=PR28&geo=PR08","curl":"curl -s 'http://127.0.0.1:8765/v1/latest?metric=population&metric=households&geo=PR28&geo=PR08'"},{"title":"Serie de compraventas inscritas en Barcelona provincia desde 2024","url":"/v1/observations?metric=sales_registered&geo=PR08&from=2024-01-01","curl":"curl -s 'http://127.0.0.1:8765/v1/observations?metric=sales_registered&geo=PR08&from=2024-01-01'"},{"title":"Comparar la tasa de vacías entre las provincias del MVP","url":"/v1/compare?metric=vacancy_ratio&zones=mvp&level=province","curl":"curl -s 'http://127.0.0.1:8765/v1/compare?metric=vacancy_ratio&zones=mvp&level=province'"},{"title":"Perfil compacto de Santander","url":"/v1/housing-profile/MU39075?compact=true","curl":"curl -s 'http://127.0.0.1:8765/v1/housing-profile/MU39075?compact=true'"},{"title":"Evidencia (sin veredicto) sobre oferta y precios en el municipio de Madrid","url":"/v1/claims/evidence?geo=MU28079&dimensions=supply_constraint,price_pressure","curl":"curl -s 'http://127.0.0.1:8765/v1/claims/evidence?geo=MU28079&dimensions=supply_constraint,price_pressure'"},{"title":"Medidas legales que afectaban a Barcelona el 15 de enero de 2025","url":"/v1/legal/measures?at=2025-01-15&geo=MU08019","curl":"curl -s 'http://127.0.0.1:8765/v1/legal/measures?at=2025-01-15&geo=MU08019'"},{"title":"Traza de una observación hasta el raw","url":"/v1/observations/5231","curl":"curl -s 'http://127.0.0.1:8765/v1/observations/5231'"},{"title":"Qué ha cambiado desde el 1 de octubre de 2026","url":"/v1/changes?since=2026-10-01","curl":"curl -s 'http://127.0.0.1:8765/v1/changes?since=2026-10-01'"},{"title":"Exportar el parque de Madrid provincia a CSV con procedencia","url":"/v1/export?metric=total_housing_stock&geo=PR28","curl":"curl -s 'http://127.0.0.1:8765/v1/export?metric=total_housing_stock&geo=PR28'"}],"error_format":{"shape":{"error":{"code":"string estable","message":"qué falló","hint":"qué hacer","suggestions":["alternativas concretas"]}},"codes":{"metric_not_found":"métrica desconocida; suggestions = códigos parecidos + /v1/metrics?q=","geography_not_found":"territorio desconocido; hint explica los formatos y /v1/geographies?q=","no_data":"sin datos para esa métrica/territorio; suggestions = niveles y periodos que SÍ existen y el territorio superior con dato","source_not_found":"fuente desconocida","observation_not_found":"id de observación inexistente","raw_file_missing":"410: el raw existe en BD pero no en este disco","validation_error":"422: parámetro con tipo/formato/valor inválido; suggestions lista cada uno","not_found":"ruta inexistente; hint apunta a GET /v1"}},"links":{"guide_json":"/v1","guide_markdown":"/v1/agent-guide.md","llms_txt":"/llms.txt","openapi":"/openapi.json","swagger":"/docs","redoc":"/redoc","dashboard":"/dashboard/"}}