191 lines
7.1 KiB
Markdown
191 lines
7.1 KiB
Markdown
# 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/<MAC>` | 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/<key>` | 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/<MAC>` | 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. |
|