# UDM Pro — referencia rápida de endpoints Base URL: `https://192.168.87.5/proxy/network/integration/v1` Auth: header `X-API-KEY: $UNIFI_API_KEY` en TODAS las requests. Todas las respuestas vienen como `{ "offset", "limit", "count", "totalCount", "data": [...] }`. ## Sites | Método | Ruta | Devuelve | |---|---|---| | GET | `/sites` | Lista de sites del controller. Para nosotros casi siempre `default`. | ```bash query.sh /sites ``` ## Devices (APs, switches, gateway) | Método | Ruta | Devuelve | |---|---|---| | GET | `/sites/{site}/devices` | Todos los devices UniFi adoptados (APs, switches, UDM). | | GET | `/sites/{site}/devices/{deviceId}` | Detalle de un device. | | GET | `/sites/{site}/devices/{deviceId}/statistics/latest` | Stats actuales: uptime, CPU/RAM, load, uplink tx/rx Bps, % retries por radio. | | POST | `/sites/{site}/devices/{deviceId}/actions` | Acciones (RESTART, etc). **No usar — la skill es read-only.** | Campos REALES del device (verificado contra el UDM): - `id`, `name`, `model`, `macAddress`, `ipAddress` - `state`: `ONLINE | OFFLINE | PROVISIONING | UPGRADING | ADOPTING | ...` - `firmwareVersion`, `firmwareUpdatable` - `features`: lista (`accessPoint`, `switching`, `gateway`, ...) - `interfaces`: lista de interfaces que el device expone (`radios`, `ports`, ...) - `supported`: bool > ⚠️ **No incluye**: `uptime` (está en `statistics/latest`), count de clientes conectados, > temperatura, info por puerto del switch, MAC del WAN. Para esos datos → Classic API. ```bash query.sh "/sites/{site}/devices" | jq '.data[] | {name, model, state, ipAddress, macAddress}' ``` Campos REALES de `/devices/{id}/statistics/latest` (verificado): - `uptimeSec`, `lastHeartbeatAt`, `nextHeartbeatAt` - `loadAverage1Min/5Min/15Min` - `cpuUtilizationPct`, `memoryUtilizationPct` - `uplink.txRateBps`, `uplink.rxRateBps` - `interfaces.radios[]`: `frequencyGHz`, `txRetriesPct` (>10% = saturación inalámbrica) ## Clients (lo conectado a tu red) | Método | Ruta | Devuelve | |---|---|---| | GET | `/sites/{site}/clients` | Clientes activos (wired + wireless). Soporta `?offset=&limit=`. | | GET | `/sites/{site}/clients/{clientId}` | Detalle de un cliente. | Campos REALES del cliente (verificado contra el UDM): - `id`, `name` (alias asignado en la UI; **NO viene `hostname` ni el name del DHCP**) - `macAddress`, `ipAddress` - `type`: `WIRED | WIRELESS` - `connectedAt` (ISO timestamp) - `uplinkDeviceId` (id del AP/switch al que está pegado) - `access.type`: `DEFAULT | ...` > ⚠️ **NO incluye**: `txBytes`/`rxBytes` (bytes consumidos), `signal`/RSSI, `rxRate`/`txRate`, > `wlanName`/SSID, `lastSeen`, `hostname`. Para esos datos → Classic API (`/stat/sta`). ```bash # Buscar por MAC (case-insensitive) query.sh "/sites/{site}/clients" | jq --arg m "AA:BB:CC:DD:EE:FF" '.data[] | select((.macAddress // "") | ascii_upcase == ($m | ascii_upcase))' # Buscar por IP query.sh "/sites/{site}/clients" | jq '.data[] | select(.ipAddress == "192.168.87.142")' # Saber a qué AP/switch está pegado un cliente (resolviendo el uplinkDeviceId) query.sh "/sites/{site}/clients" | jq '.data[] | {name, ip: .ipAddress, uplinkDeviceId}' query.sh "/sites/{site}/devices" | jq '.data[] | {id, name}' # mapeo manual ``` ## Networks (VLANs / redes definidas en el UDM) | Método | Ruta | Devuelve | |---|---|---| | GET | `/sites/{site}/networks` | Lista de networks configuradas (VLANs). | Campos: `id`, `name`, `vlanId`, `enabled`, `default`, `management` (`GATEWAY`, `WIFI`, ...), `zoneId`, `metadata.origin` (`SYSTEM_DEFINED | USER_DEFINED`). > ⚠️ **NO** devuelve subnet, DHCP range, gateway IP, ni reglas de firewall — solo metadatos. ## Hotspot vouchers | Método | Ruta | |---|---| | GET | `/sites/{site}/hotspot/vouchers` | > Irrelevante para nosotros — el portal cautivo lo maneja `radiusNucleo` con FreeRADIUS, > no el hotspot nativo del UDM. ## Info global | Método | Ruta | Devuelve | |---|---|---| | GET | `/info` | `{ applicationVersion }` — versión de UniFi Network App. | ## Paginación Todos los listados aceptan `?offset=N&limit=M` (default offset=0, limit=25, max 200). Si `count < totalCount`, hay más páginas: ```bash query.sh "/sites/{site}/clients?limit=200&offset=0" query.sh "/sites/{site}/clients?limit=200&offset=200" ``` ## Classic API (vía `query-classic.sh`) Login flow stateful (cookie + CSRF cacheados 25 min). Path corto se prefija a `/proxy/network/api/s/$UNIFI_SITE_NAME`. Site name = `default` (no UUID). Respuesta envuelta en `{ "meta": { "rc": "ok" }, "data": [...] }` (vs Integration que usa `{ "data": [...], "totalCount": N }`). ### Estado del sistema | Path corto | Devuelve | |---|---| | `/stat/health` | Health por subsistema: `wlan`, `wan`, `www`, `lan`, `vpn`. Status `ok/warning/error`, counts, ISP, throughput, uptime. **Lo más útil para diagnóstico rápido.** | | `/stat/sysinfo` | Info del controller (versión, build, hostname, license). | | `/stat/dashboard` | Resumen agregado (similar al dashboard de la UI). | ### Clientes (con campos que la Integration NO devuelve) | Path corto | Devuelve | |---|---| | `/stat/sta` | Clientes activos con `tx_bytes`, `rx_bytes`, `signal`, `rssi`, `essid`, `radio`, `radio_proto`, `tx_rate`, `rx_rate`, `hostname`, `uptime`, `last_seen`. | | `/rest/user` | TODOS los users (incluso offline), con `note`, `usergroup_id`, etc. | | `/stat/user/` | Detalle de un user específico por MAC. | ```bash # Top 10 consumidores ahora mismo query-classic.sh /stat/sta | python -c " import json, sys d = json.load(sys.stdin)['data'] top = sorted(d, key=lambda c: -(c.get('tx_bytes',0)+c.get('rx_bytes',0)))[:10] for c in top: print(c.get('hostname','?'), c.get('mac'), c.get('tx_bytes',0)+c.get('rx_bytes',0)) " ``` ### Eventos y alarmas | Path corto | Devuelve | |---|---| | `/stat/event` | Eventos del controller (login, roaming, AP up/down, etc). Acepta `?within=24` (horas) y `?_limit=N`. | | `/stat/alarm` | Alarmas activas. | | `/list/alarm` | Histórico de alarmas. | ### Configs (read-only via View Only) | Path corto | Devuelve | |---|---| | `/list/wlanconf` o `/rest/wlanconf` | SSIDs definidas (nombre, banda, security, vlan). | | `/rest/networkconf` | Networks/VLANs (subnet, DHCP range, gateway). | | `/rest/firewallrule` | Reglas de firewall. | | `/rest/portforward` | Port forwards. | | `/rest/setting/` | Settings del site. | ### DPI / App usage | Path corto | Devuelve | |---|---| | `/stat/stadpi` | DPI por cliente (qué apps consumen, cuántos bytes). | | `/stat/sitedpi` | DPI agregado del site. | ### Devices con stats completos | Path corto | Devuelve | |---|---| | `/stat/device` | Devices con stats embebidos (CPU, mem, **temperatura**, throughput por puerto, **count de clientes** por AP, etc). Mucho más rico que `/sites/{site}/devices` de Integration. | | `/stat/device/` | Detalle de un device. | ## Errores comunes | HTTP | Causa probable | |---|---| | 401 | API Key inválida o caducada. Regenerá. | | 403 | El admin que generó la key no tiene permiso sobre ese site. | | 404 | Path mal escrito o site/device/client no existe. | | 5xx + cuerpo HTML | Le pegaste a UniFi OS root, no a `/proxy/network/integration/v1`. | | connection refused / timeout | No estás en la LAN o el UDM está caído. |