{"openapi":"3.1.0","info":{"title":"API de la dureza del agua en España (El mapa del agua)","version":"2026-10-30","summary":"Dureza del agua de consumo de cada municipio español, por código INE o código postal, con la fuente y la fecha del análisis.","description":"Una petición GET, sin clave, sin registro y con CORS abierto.\n\n- **Sin límite de peticiones** ni por clave ni por IP. Las respuestas con dato se cachean una hora (`s-maxage=3600`); los errores no se cachean.\n- **Sin SLA ni soporte comprometido.** Para muchas consultas, descarga el dataset entero en https://elmapadelagua.com/datos.\n- **Cuando un municipio no tiene dato**, la respuesta es 200 con `estado: \"sin-dato\"` y el motivo. Nunca se devuelve una cifra estimada.\n- La respuesta puede ganar campos nuevos; no se quitan ni se renombran. Ignora los que no conozcas.\n\n**Fuentes y atribución obligatoria** (quien consume la API redistribuye el dato):\n\n- SINAC — Sistema de Información Nacional de Agua de Consumo: La dureza del agua de cada municipio, con su fecha de análisis. Cita: «Origen de los datos: Ministerio de Sanidad, Consumo y Bienestar Social». Condiciones: https://www.sanidad.gob.es/avisoLegal/home.htm\n- CartoCiudad — Instituto Geográfico Nacional: La correspondencia entre códigos postales y municipios. Cita: «CC BY 4.0 scne.es». Condiciones: https://creativecommons.org/licenses/by/4.0/deed.es\n- INE — Instituto Nacional de Estadística: El nombre oficial, el código y la población de los municipios. Cita: «Elaboración propia con datos extraídos del sitio web del INE: www.ine.es». Condiciones: https://www.ine.es/ss/Satellite?L=es_ES&c=Page&cid=1254735849170&p=1254735849170&pagename=Ayuda%2FINELayout\n\n**Condiciones de reutilización del Ministerio de Sanidad:**\n\n- No desnaturalizar el sentido de la información.\n- Citar la fuente de los documentos objeto de reutilización.\n- Mencionar la fecha de la última actualización de los documentos reutilizados.\n- No indicar, insinuar ni sugerir que el Ministerio de Sanidad o el INE participan, patrocinan o apoyan la reutilización.\n- Conservar, no alterar y no suprimir los metadatos sobre la fecha de actualización.\n\nNi el Ministerio de Sanidad ni el INE participan, patrocinan ni apoyan esta reutilización.\nLos ejemplos de esta especificación son respuestas reales pedidas a producción el 2026-10-30; el dato se refresca cada noche y puede haber cambiado.","license":{"name":"Datos: condiciones de reutilización del Ministerio de Sanidad, CC BY 4.0 (CartoCiudad) e INE","url":"https://elmapadelagua.com/datos/licencia.txt"}},"externalDocs":{"description":"Documentación completa, en castellano","url":"https://elmapadelagua.com/api-dureza-agua"},"servers":[{"url":"https://elmapadelagua.com"}],"paths":{"/api/dureza":{"get":{"operationId":"consultarDureza","security":[],"summary":"Dureza del agua de un municipio","description":"Se manda **exactamente uno** de los dos parámetros, `ine` o `cp`. Los dos a la vez, ninguno, o uno que no sean cinco dígitos responde 400.","parameters":[{"name":"ine","in":"query","required":false,"description":"Código INE del municipio: cinco dígitos, con los ceros a la izquierda. Identifica un municipio y solo uno.","schema":{"type":"string","pattern":"^\\d{5}$"},"example":"28079"},{"name":"cp","in":"query","required":false,"description":"Código postal de cinco dígitos. Si cubre varios municipios no se elige uno: responde `sin-dato` con motivo `cp-multimunicipio`.","schema":{"type":"string","pattern":"^\\d{5}$"},"example":"46001"}],"responses":{"200":{"description":"Hay respuesta: `encontrado` o `sin-dato`. Los dos son resultados válidos; `sin-dato` no es un error.","headers":{"Access-Control-Allow-Origin":{"description":"Siempre `*`, también en las respuestas de error.","schema":{"type":"string","const":"*"}},"Link":{"description":"RFC 8288: `rel=\"license\"` apunta a las condiciones de reutilización y `rel=\"help\"` a la documentación.","schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string","const":"public, max-age=0, s-maxage=3600, stale-while-revalidate=86400"}}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/RespuestaPorIne"},{"$ref":"#/components/schemas/RespuestaPorCp"}]},"examples":{"porIne":{"summary":"Por código INE (Madrid)","value":{"ok":true,"data":{"estado":"encontrado","ine":"28079","registro":{"municipioIne":"28079","municipioNombre":"Madrid","provincia":"Madrid","fh":3.2,"fuente":"SINAC — Ministerio de Sanidad (consulta ciudadana)","urlFuente":"https://sinac.sanidad.gob.es/","fechaDato":"2026-09-29","confianza":"medido-operadora"},"cp":"28001"}}},"porCp":{"summary":"Por código postal (València)","value":{"ok":true,"data":{"estado":"encontrado","cp":"46001","registro":{"municipioIne":"46250","municipioNombre":"València","provincia":"Valencia/València","fh":43,"fuente":"SINAC — Ministerio de Sanidad (consulta ciudadana)","urlFuente":"https://sinac.sanidad.gob.es/","fechaDato":"2026-09-11","confianza":"agregado-zona"}}}},"sinAnalitica":{"summary":"Hueco declarado (Vitoria-Gasteiz)","value":{"ok":true,"data":{"estado":"sin-dato","ine":"01059","municipioNombre":"Vitoria-Gasteiz","provincia":"Álava","motivo":"sin-analitica-publica"}}},"ineDesconocido":{"summary":"Código INE que no está en el callejero","value":{"ok":true,"data":{"estado":"sin-dato","ine":"99999","motivo":"ine-desconocido"}}},"cpDesconocido":{"summary":"Código postal que no está en CartoCiudad","value":{"ok":true,"data":{"estado":"sin-dato","cp":"99999","motivo":"cp-desconocido"}}}}}}},"400":{"description":"Parámetro no válido, o se mandaron los dos a la vez.","headers":{"Access-Control-Allow-Origin":{"description":"Siempre `*`, también en las respuestas de error.","schema":{"type":"string","const":"*"}},"Link":{"description":"RFC 8288: `rel=\"license\"` apunta a las condiciones de reutilización y `rel=\"help\"` a la documentación.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RespuestaError"},"examples":{"ineMalFormado":{"summary":"INE de cuatro dígitos","value":{"ok":false,"error":{"code":"bad_request","message":"Codigo INE no valido (5 digitos)."}}},"dosParametros":{"summary":"cp e ine a la vez","value":{"ok":false,"error":{"code":"bad_request","message":"Indica cp o ine, no los dos: podrian no referirse al mismo municipio."}}}}}}},"500":{"description":"No se ha podido consultar. Es una avería nuestra y nunca se degrada a `sin-dato`. Reintenta.","headers":{"Access-Control-Allow-Origin":{"description":"Siempre `*`, también en las respuestas de error.","schema":{"type":"string","const":"*"}},"Link":{"description":"RFC 8288: `rel=\"license\"` apunta a las condiciones de reutilización y `rel=\"help\"` a la documentación.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RespuestaError"}}}}}},"options":{"operationId":"preflightDureza","security":[],"summary":"Preflight CORS","responses":{"204":{"description":"Respuesta al preflight, con las cabeceras CORS.","headers":{"Access-Control-Allow-Origin":{"description":"Siempre `*`, también en las respuestas de error.","schema":{"type":"string","const":"*"}},"Link":{"description":"RFC 8288: `rel=\"license\"` apunta a las condiciones de reutilización y `rel=\"help\"` a la documentación.","schema":{"type":"string"}},"Access-Control-Allow-Methods":{"schema":{"type":"string","const":"GET, HEAD, OPTIONS"}},"Access-Control-Max-Age":{"schema":{"type":"string","const":"86400"}}}}}}}},"components":{"schemas":{"NivelConfianza":{"type":"string","enum":["medido-municipio","medido-operadora","agregado-zona"],"description":"Cómo de cerca del grifo está la medida. No existe un nivel «estimado»: un hueco se declara hueco."},"HardnessRecord":{"type":"object","description":"Un análisis de dureza con su fuente y su fecha. Ningún campo es opcional.","required":["municipioIne","municipioNombre","provincia","fh","fuente","urlFuente","fechaDato","confianza"],"properties":{"municipioIne":{"type":"string","pattern":"^\\d{5}$","description":"Código INE del municipio al que corresponde el análisis."},"municipioNombre":{"type":"string","minLength":1,"description":"Nombre oficial del callejero del INE, tal cual, incluidas las formas bilingües (València, Araba/Álava)."},"provincia":{"type":"string","minLength":1,"description":"Nombre oficial de la provincia según el INE."},"fh":{"type":"number","minimum":0,"maximum":200,"description":"Dureza en grados franceses (°fH), la unidad del SINAC. 1 °fH = 10 mg/L de CaCO3; °dH = °fH × 0,56."},"fuente":{"type":"string","minLength":1,"description":"De dónde sale este registro concreto, redactado para citarlo."},"urlFuente":{"type":"string","format":"uri","description":"Dónde comprobarlo en el origen. Nunca viene vacío."},"fechaDato":{"type":"string","format":"date","description":"Fecha del análisis (AAAA-MM-DD). Es la que hay que citar, no la de la consulta."},"confianza":{"$ref":"#/components/schemas/NivelConfianza"}}},"DurezaPorIne":{"description":"Resultado de `?ine=`. La respuesta puede ganar campos nuevos; no se quitan ni se renombran. Ignora los que no conozcas.","oneOf":[{"$ref":"#/components/schemas/DurezaPorIneEncontrado"},{"$ref":"#/components/schemas/DurezaPorIneSinDato"}],"discriminator":{"propertyName":"estado","mapping":{"encontrado":"#/components/schemas/DurezaPorIneEncontrado","sin-dato":"#/components/schemas/DurezaPorIneSinDato"}}},"DurezaPorIneEncontrado":{"type":"object","required":["estado","ine","registro","cp"],"properties":{"estado":{"type":"string","const":"encontrado"},"ine":{"type":"string","pattern":"^\\d{5}$"},"registro":{"$ref":"#/components/schemas/HardnessRecord"},"cp":{"type":["string","null"],"pattern":"^\\d{5}$","description":"Un código postal representativo del municipio, o null. Nunca se rellena con el INE."}}},"DurezaPorIneSinDato":{"type":"object","required":["estado","ine","motivo"],"properties":{"estado":{"type":"string","const":"sin-dato"},"ine":{"type":"string","pattern":"^\\d{5}$"},"municipioNombre":{"type":"string"},"provincia":{"type":"string"},"motivo":{"type":"string","enum":["sin-analitica-publica","ine-desconocido"],"description":"`sin-analitica-publica`: el municipio existe y no hay analítica publicada que citar. `ine-desconocido`: el código no está en el callejero del INE."}}},"HardnessLookup":{"description":"Resultado de `?cp=`. La respuesta puede ganar campos nuevos; no se quitan ni se renombran. Ignora los que no conozcas.","oneOf":[{"$ref":"#/components/schemas/HardnessLookupEncontrado"},{"$ref":"#/components/schemas/HardnessLookupSinDato"}],"discriminator":{"propertyName":"estado","mapping":{"encontrado":"#/components/schemas/HardnessLookupEncontrado","sin-dato":"#/components/schemas/HardnessLookupSinDato"}}},"HardnessLookupEncontrado":{"type":"object","required":["estado","cp","registro"],"properties":{"estado":{"type":"string","const":"encontrado"},"cp":{"type":"string","pattern":"^\\d{5}$"},"registro":{"$ref":"#/components/schemas/HardnessRecord"}}},"HardnessLookupSinDato":{"type":"object","required":["estado","cp","motivo"],"properties":{"estado":{"type":"string","const":"sin-dato"},"cp":{"type":"string","pattern":"^\\d{5}$"},"municipioNombre":{"type":"string"},"motivo":{"type":"string","enum":["sin-analitica-publica","cp-multimunicipio","cp-desconocido"],"description":"`cp-multimunicipio`: el código postal cubre varios municipios y no se elige uno; pregunta por `ine`. `cp-desconocido`: no aparece en CartoCiudad."}}},"RespuestaPorIne":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/DurezaPorIne"}}},"RespuestaPorCp":{"type":"object","required":["ok","data"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/HardnessLookup"}}},"RespuestaError":{"type":"object","required":["ok","error"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Hoy este endpoint solo emite `bad_request` (400) e `internal` (500). Sin `enum` a propósito: si mañana aparece otro código, un cliente generado no debe romperse."},"message":{"type":"string","description":"Explicación en castellano, para depurar."}}}}}}}}