Datos abiertos
Reportes diarios del agua en cada colonia de la ZMG: cómo llegó (normal, poca o nada) y cómo se veía (clarita, turbia o maloliente), según los reportes anónimos de los vecinos y el calendario de suspensiones que publica SIAPA.
Overview #
Cada noche, a las 00:15 (hora de Ciudad de México), se suma el día que acaba de terminar. El día en curso nunca aparece.
aguas! ZMG es un proyecto independiente; no tiene relación con SIAPA.
Endpoints #
Son dos endpoints públicos: no necesitas API key ni cuenta. Los dos responden a GET y traen los mismos datos.
GET https://aguaszmg.mx/api/v1/daily.csv
GET https://aguaszmg.mx/api/v1/daily.json
daily.csv: UTF-8 con BOM, separado por comas (RFC 4180), se abre directo en Excel.daily.json: un objeto condata(los registros) ymeta(datos de la consulta). Los conteos son números onull.
Quick download #
Los últimos 31 días, para descargar con un click.
Query parameters #
| Parameter | Type | Description |
|---|---|---|
from |
YYYY-MM-DD |
El primer día que quieres, incluido. Si no lo pones, empieza 30 días antes de to. |
to |
YYYY-MM-DD |
El último día que quieres, incluido. Si no lo pones, es ayer. Tiene que ser un día que ya terminó: hoy no se puede pedir. |
Response #
Cada registro es una colonia en un día. Un día publicado no cambia.
Request
curl -OJ \
"https://aguaszmg.mx/api/v1/daily.csv?from=2026-10-13&to=2026-11-12"
Fields #
| Field | Type | Description |
|---|---|---|
date |
string (YYYY-MM-DD) | El día al que corresponde el registro. |
neighborhood_slug |
string | Identificador de la colonia en aguas! ZMG. No cambia aunque SIAPA cambie sus ids. |
siapa_id |
string | El id que SIAPA le daba a la colonia ese día. |
neighborhood |
string | Nombre de la colonia, tal como viene en el archivo de SIAPA. |
municipality |
string | null | Municipio, tal como viene en el archivo de SIAPA; null si no lo trae. |
postal_code |
string | null | Código postal, como texto para conservar los ceros a la izquierda; null si no lo trae. |
zones |
array of strings | Zonas de SIAPA a las que pertenecía la colonia ese día. En el CSV van separadas por comas (1,5,6); en el JSON son un arreglo, vacío si no tiene zona. |
siapa_suspension |
enum (string) | Si el calendario de SIAPA tenía suspensión ese día. Valores abajo. |
status |
enum (string) | Cómo estuvo el agua ese día según los vecinos. Valores abajo. |
supply_normal |
integer | Reportes de que el agua llegó normal. |
supply_low |
integer | Reportes de que llegó poca agua. |
supply_none |
integer | Reportes de que no llegó agua. |
quality_clear |
integer | Reportes de agua clarita. |
quality_turbid |
integer | Reportes de agua turbia (en el mapa se ve café). |
quality_foul |
integer | Reportes de agua maloliente. |
Status values #
status
| Value | Meaning |
|---|---|
no_water |
Nada: no llegó agua. |
foul |
Maloliente: el agua llegó con mal olor. |
brown |
Café: el agua llegó turbia. |
clear |
Clarita: el agua llegó limpia. |
insufficient_data |
Pocos datos: hubo menos de 3 reportes ese día. |
no_reports |
Sin reportes: nadie reportó ese día. |
siapa_suspension
| Value | Meaning |
|---|---|
full |
Todas las zonas de la colonia estaban suspendidas ese día. |
partial |
Solo una parte de sus zonas. |
none |
Ninguna (o la colonia no tiene zona). |
Errors #
Status codes
| HTTP | Meaning |
|---|---|
| 200 | Todo bien; los datos vienen en el body. |
| 304 | Nada cambió después de tu última descarga (mandaste If-None-Match); la respuesta no trae body. |
| 400 | Algún parámetro no es válido; el body explica el error. |
Error codes
| HTTP | Code | When |
|---|---|---|
| 400 | invalid_date |
from o to no están en formato YYYY-MM-DD. |
| 400 | invalid_range |
from cae después de to. |
| 400 | range_too_large |
Pediste más de 31 días. |
| 400 | date_not_published |
to es hoy o un día futuro; solo publicamos días que ya terminaron. |
Headers & caching #
Las respuestas exitosas incluyen estos headers:
| Header | Description |
|---|---|
Content-Type |
text/csv; charset=utf-8 o application/json; charset=utf-8. |
Content-Disposition |
Solo en el CSV: attachment; filename="aguaszmg-daily_<from>_<to>.csv". |
ETag |
Viene en cada 200. Mándalo de vuelta en If-None-Match. |
Cache-Control |
public, max-age=<segundos que faltan para las 00:15 de Ciudad de México>. |
El día nuevo se publica a las 00:15 (hora de Ciudad de México), así que la respuesta no cambia antes de esa hora. Si mandas If-None-Match con el ETag de tu última descarga, recibes un 304 cuando no hay nada nuevo.
Examples #
Últimos 31 días
curl -OJ \
"https://aguaszmg.mx/api/v1/daily.csv?from=2026-10-13&to=2026-11-12"
curl -sS \
"https://aguaszmg.mx/api/v1/daily?from=2026-10-13&to=2026-11-12"
Últimos 7 días
curl -OJ \
"https://aguaszmg.mx/api/v1/daily.csv?from=2026-11-06&to=2026-11-12"
curl -sS \
"https://aguaszmg.mx/api/v1/daily?from=2026-11-06&to=2026-11-12"
Descarga condicional con If-None-Match
La primera descarga guarda el ETag; la segunda solo trae datos si hay algo nuevo; si no, responde 304.
curl -sS -D headers.txt -o daily.csv \
"https://aguaszmg.mx/api/v1/daily.csv?from=2026-10-13&to=2026-11-12"
etag=$(grep -i '^etag:' headers.txt | cut -d' ' -f2- | tr -d '\r')
curl -sS -o /dev/null -w '%{http_code}\n' \
-H "If-None-Match: $etag" \
"https://aguaszmg.mx/api/v1/daily.csv?from=2026-10-13&to=2026-11-12"
License #
Estos datos están bajo CC BY 4.0: puedes copiarlos, compartirlos y adaptarlos, incluso para uso comercial, siempre que des crédito a aguas! ZMG.
How to cite #
aguas! ZMG. Reportes diarios por colonia. https://aguaszmg.mx/datos. Consultado el 13 de noviembre de 2026. CC BY 4.0.