CLI Reference
All 28 commands, flags, output formats, and gotchas
Every command supports --help for exhaustive flag listings. This page documents subcommands, key flags, and gotchas you wonβt find in --help.
API legend: I = Integration API (API key). L = Session API (API key on UniFi OS, or username/password). H = Works in any mode, enriched when session HTTP access exists.
πCommands
| Command | Alias | API | Description |
|---|---|---|---|
devices | dev, d | H | Manage adopted and pending devices |
clients | cl | H | Manage connected clients and DHCP reservations |
networks | net, n | I | Manage networks and VLANs |
wifi | w | I | Manage WiFi broadcasts (SSIDs) |
firewall | fw | Mixed | Manage firewall policies, zones, and groups |
nat | L | Manage NAT policies (masquerade, SNAT, DNAT) | |
acl | I | Manage ACL rules | |
dns | I | Manage DNS policies (local records) | |
traffic-lists | I | Manage traffic matching lists | |
hotspot | I | Manage hotspot vouchers | |
vpn | Mixed | View VPN inventory, session site-to-site, remote-access, and client VPN records, OpenVPN helpers, connections, WireGuard peers, magic site-to-site configs, and VPN settings | |
events | L | View and stream events | |
alarms | L | Manage alarms | |
stats | L | Query statistics and reports | |
sites | L | Manage sites | |
admin | L | Administrator management | |
system | sys | Mixed | System operations and info |
settings | L | Read and write site-level settings sections | |
topology | topo | H | Show network topology tree |
dpi | Mixed | DPI reference data and control | |
radius | I | View RADIUS profiles | |
wans | I | View WAN interfaces | |
countries | I | List available country codes | |
cloud | Cloud | Query the Site Manager fleet (consoles, sites, devices, ISP, SD-WAN) | |
config | Local | Manage CLI configuration | |
completions | Local | Generate shell completions | |
api | L | Raw API passthrough (GET/POST/PUT/PATCH/DELETE any endpoint) | |
tui | H | Launch the real-time terminal dashboard |
List commands default to 25 rows. Pass --all or --limit 200 for complete results.
πDevices
unifly devices list # All adopted devices
unifly devices list --filter "state.eq('Online')" # Filter by status
unifly devices get <ID|MAC> # Device details
unifly devices pending # Devices awaiting adoption
unifly devices adopt <MAC> # Adopt a pending device
unifly devices remove <ID|MAC> # Unadopt a device
unifly devices restart <ID|MAC> # Restart
unifly devices locate <MAC> --on true # Flash LED (--on false to stop)
unifly devices port-cycle <ID|MAC> <PORT> # Power-cycle a PoE port
unifly devices stats <ID|MAC> # Real-time device stats
unifly devices upgrade <MAC> # Trigger firmware upgrade
unifly devices provision <MAC> # Force re-provision config
unifly devices speedtest # WAN speed test (gateway only)
unifly devices tags # List device tags
Gotchas: restart, locate, upgrade, provision, speedtest, and port-cycle require Session API access. list and get work with any auth mode but return richer data when session HTTP access exists (client count, uplink MAC).
πSwitch Ports (config-as-code)
unifly devices ports <ID|MAC> # Current port config
unifly devices ports <ID|MAC> --with-clients # Annotate with connected clients
unifly devices ports-export <ID|MAC> # Export overrides as JSONC
unifly devices ports-export <ID|MAC> --all # Include every port
unifly devices port-set <ID|MAC> 5 --mode access --native-vlan IoT
unifly devices port-set <ID|MAC> -F ports.jsonc # Apply a JSONC file
unifly devices port-set <ID|MAC> 5 --reset # Back to controller defaults
Port indices are 1-based, matching the controllerβs wire format. port-set -F accepts a JSONC payload (comments and trailing commas allowed) with splice semantics: ports not listed keep their existing override, and a per-port "reset": true removes that portβs override entirely. --with-clients adds connection annotations, and on ports-export it prepends // last-seen <timestamp>: <mac> comment lines for git-diff drift detection. See Switch Ports for the full workflow and payload schema.
πClients
unifly clients list # Connected clients
unifly clients list --type wireless # Filter by type
unifly clients find "ring-doorbell" # Search by name, IP, or MAC
unifly clients get <MAC> # Client details
unifly clients reservations # All DHCP reservations
unifly clients set-ip <MAC> --ip 10.0.10.50 # Create DHCP reservation
unifly clients set-ip <MAC> --ip 10.0.10.50 --network <ID> # Scoped to network
unifly clients remove-ip <MAC> # Remove DHCP reservation
unifly clients block <MAC> # Block from connecting
unifly clients unblock <MAC> # Unblock
unifly clients kick <MAC> # Force reconnection
unifly clients authorize <MAC> --minutes 60 # Authorize guest access
unifly clients unauthorize <MAC> # Revoke guest access
unifly clients forget <MAC> # Remove from client history
unifly clients roams <MAC> # Roaming history for a client
unifly clients wifi <MAC> # WiFi experience details for a client
Gotchas: list returns enriched data in Hybrid mode (traffic bytes, hostname, wireless, VLAN). block/unblock/kick/forget and DHCP reservation commands require Session API.
πNetworks
unifly networks list # All networks/VLANs
unifly networks get <ID> # Full network details
unifly networks create --name "IoT" --management gateway --vlan 20 --ipv4-host "10.0.20.1/24"
unifly networks create -F network.json # Create from JSON file
unifly networks update <ID> --enabled false
unifly networks delete <ID>
unifly networks refs <ID> # What depends on this network?
Gotchas: list returns summary data without ipv4Configuration. Use get for full config. refs is the only pre-delete dependency check; use it before deleting.
πWiFi
unifly wifi list # All SSIDs
unifly wifi get <ID> # SSID details
unifly wifi create --name "Guest" --network <ID> --security wpa2-personal --passphrase "..."
unifly wifi create -F wifi.json # Create from JSON file
unifly wifi update <ID> --enabled false
unifly wifi delete <ID>
unifly wifi neighbors # Scan nearby APs (RF environment)
unifly wifi channels # Channel utilization analysis
Gotchas: Serde defaults to PascalCase for enums in --from-file JSON. Use "Wpa2Personal" not "wpa2_personal". The --security flag on the CLI accepts kebab-case (wpa2-personal). neighbors and channels are read-only observability commands that query Session API data.
πFirewall
πPolicies
unifly firewall policies list
unifly firewall policies get <ID>
unifly firewall policies create --name "Block IoT" --action block \
--source-zone <ID> --dest-zone <ID>
unifly firewall policies create -F policy.json
unifly firewall policies update <ID> -F policy.json
unifly firewall policies patch <ID> --enabled false # Quick toggle
unifly firewall policies patch <ID> --logging true # Toggle logging
unifly firewall policies delete <ID>
unifly firewall policies reorder --source-zone <ID> --dest-zone <ID> --get
unifly firewall policies reorder --source-zone <ID> --dest-zone <ID> --set <ID1,ID2,...>
Gotchas: patch is the fast path for toggling enabled/logging only. Use update for other fields. reorder with --get shows current order; --set applies a new order. First-match wins, so ordering matters.
πZones
unifly firewall zones list
unifly firewall zones get <ID>
unifly firewall zones create --name "IoT Zone" --networks <ID1,ID2>
unifly firewall zones create -F zone.json
unifly firewall zones update <ID> --networks <ID1,ID2>
unifly firewall zones delete <ID>
πGroups
unifly firewall groups list
unifly firewall groups list --type port-group
unifly firewall groups get <ID>
unifly firewall groups create --name "Web Ports" --type port-group --members "80,443,8000-8002"
unifly firewall groups create --name "IoT Nets" --type address-group --members "10.0.30.0/24"
unifly firewall groups update <ID> --members "80,443"
unifly firewall groups delete <ID>
Gotchas: groups use the Session API (rest/firewallgroup), not Integration; an API key on UniFi OS is sufficient. Types: port-group (default), address-group, ipv6-address-group. The external_id UUID in group responses is what firewall policies reference. Policy create/update resolve group names for you via --src-port-group / --dst-port-group / --src-address-group / --dst-address-group flags (or dst_port_group / dst_address_group shorthand fields in --from-file JSON).
πNAT
unifly nat policies list
unifly nat policies get <ID>
unifly nat policies create --name "Masquerade" --type masquerade --interface-id <ID>
unifly nat policies create -F nat.json
unifly nat policies update <ID> --name "New Name" --enabled true
unifly nat policies delete <ID>
Use nat policies update <ID> to modify an existing rule. Pass any combination of --name, --type, --enabled, address/port flags, or --from-file. Only the specified fields are changed.
NAT types: masquerade (outgoing interface address), source (explicit rewrite), destination (port forwarding/DNAT). NAT routes through the Session v2 API: an API key on UniFi OS is sufficient, and session-only profiles work too (nat policies list populates from the session refresh snapshot). Only pure-Integration setups without session HTTP access cannot manage NAT.
πACL
unifly acl list
unifly acl get <ID>
unifly acl create --name "Block printer" --rule-type ipv4 --action block \
--source-zone <ID> --dest-zone <ID>
unifly acl create -F acl.json
unifly acl update <ID> -F acl.json
unifly acl delete <ID>
unifly acl reorder --get # Current order
unifly acl reorder --set <ID1,ID2,...> # Apply new order
πDNS
unifly dns list
unifly dns get <ID>
unifly dns create --record-type a --domain "nas.home" --value "10.0.10.5"
unifly dns create -F dns.json
unifly dns update <ID> -F dns.json
unifly dns delete <ID>
Supported record types: a, aaaa, cname, mx, txt, srv, forward. The --record-type values are lowercase; uppercase A is rejected by argument parsing. Table output displays the familiar short uppercase names (A, AAAA, β¦).
πTraffic Lists
unifly traffic-lists list
unifly traffic-lists get <ID>
unifly traffic-lists create --name "Ad servers" --list-type ipv4 --items "1.2.3.4,5.6.7.8"
unifly traffic-lists create -F list.json
unifly traffic-lists update <ID> -F list.json
unifly traffic-lists delete <ID>
List types: ports, ipv4, ipv6. Referenced by firewall policies, NAT, and ACLs.
πEvents
unifly events list # Recent events (last 24h)
unifly events list --within 4 # Events from last 4 hours
unifly events list --limit 100 # More results
unifly events watch # Live event feed (WebSocket)
unifly events watch --types Device # Filter by category
unifly events watch --types Device,Client # Multiple categories
The --types flag accepts EventCategory values (case-insensitive): Device, Client, Network, System, Admin, Firewall, Vpn, Unknown.
--types takes category names, not EVT_* glob patterns. Use Device not EVT_SW_*.
πStatistics
unifly stats site # Site-level stats
unifly stats device # Per-device bandwidth
unifly stats client # Per-client stats
unifly stats gateway # Gateway stats (WAN, uptime)
unifly stats dpi # DPI application breakdown
unifly stats dpi --group-by by-cat # Group by category
unifly stats gateway --interval 5m # High-resolution data
unifly stats site --interval daily # Long-term trends
Supported intervals: 5m (high resolution), hourly (default), daily, monthly.
πHotspot
unifly hotspot list
unifly hotspot get <ID>
unifly hotspot create --name "Day Pass" --count 10 --minutes 1440
unifly hotspot delete <ID>
unifly hotspot purge --filter "status.eq('EXPIRED')" # Bulk delete
πAdmin
unifly admin list # List site administrators
unifly admin invite --name "Alex" --email "alex@example.com" --role admin
unifly admin revoke <ADMIN_ID> # Positional, not --email
unifly admin update <ADMIN_ID> --role readonly
Gotcha: revoke takes a positional admin ID, not an email flag.
πAlarms
unifly alarms list # All alarms
unifly alarms list --unarchived # Active alarms only
unifly alarms archive <ID> # Archive one alarm
unifly alarms archive-all # Archive everything
πDPI
unifly dpi apps # List known applications (Integration)
unifly dpi categories # List known categories (Integration)
unifly dpi status # Current DPI state (Session)
unifly dpi enable # Turn on DPI (Session)
unifly dpi disable # Turn off DPI (Session)
πSystem
unifly system info # Application version (Integration)
unifly system health # Site health summary (Session)
unifly system sysinfo # Controller system info (Session)
unifly system backup create # Create backup
unifly system backup list # List backups
unifly system backup download <FILENAME> # Download backup
unifly system backup delete <FILENAME> # Delete backup
unifly system reboot # Reboot hardware (UDM only)
unifly system poweroff # Power off hardware (UDM only)
reboot and poweroff are destructive and require confirmation (-y to skip).
πVPN
unifly vpn servers # List VPN servers (Integration)
unifly vpn tunnels # List site-to-site tunnels (Integration)
unifly vpn status # Live IPsec tunnel status
unifly vpn health # VPN subsystem health
unifly vpn site-to-site list # List site-to-site VPN records
unifly vpn site-to-site get <ID> # Inspect one site-to-site VPN record
unifly vpn site-to-site create -F vpn.json # Create a site-to-site VPN
unifly vpn site-to-site update <ID> -F vpn.json # Update a site-to-site VPN
unifly vpn site-to-site delete <ID> # Delete a site-to-site VPN
unifly vpn remote-access list # List remote-access VPN servers
unifly vpn remote-access get <ID> # Inspect one remote-access VPN server
unifly vpn remote-access create -F vpn.json # Create a remote-access VPN server
unifly vpn remote-access update <ID> -F vpn.json # Update a remote-access VPN server
unifly vpn remote-access suggest-port # Suggest available OpenVPN ports
unifly vpn remote-access download-config <ID> # Download an OpenVPN client config
unifly vpn remote-access delete <ID> # Delete a remote-access VPN server
unifly vpn clients list # List configured VPN clients
unifly vpn clients get <ID> # Inspect one configured VPN client
unifly vpn clients create -F vpn.json # Create a configured VPN client
unifly vpn clients update <ID> -F vpn.json # Update a configured VPN client
unifly vpn clients delete <ID> # Delete a configured VPN client
unifly vpn connections list # List VPN client connections
unifly vpn connections get <ID> # Inspect one VPN client connection
unifly vpn connections restart <ID> # Restart one VPN client connection
unifly vpn peers list [SERVER_ID] # List WireGuard peers, optionally by server
unifly vpn peers get <SERVER_ID> <ID> # Inspect one WireGuard peer
unifly vpn peers create <SERVER_ID> -F peer.json # Create a WireGuard peer
unifly vpn peers update <SERVER_ID> <ID> -F peer.json # Update a WireGuard peer
unifly vpn peers delete <SERVER_ID> <ID> # Delete a WireGuard peer
unifly vpn peers subnets # List subnets already used by peers
unifly vpn magic-site-to-site list # List magic site-to-site VPN configs
unifly vpn magic-site-to-site get <ID> # Inspect one magic site-to-site VPN config
unifly vpn settings list # List VPN-related site settings
unifly vpn settings get teleport # Inspect one VPN setting
unifly vpn settings set teleport --enabled true # Toggle a VPN setting
unifly vpn settings patch peer-to-peer -F peer.json # Apply a JSON payload
Gotchas: servers and tunnels are read-only Integration API inventory; everything else is Session-backed and works with an API key on UniFi OS. Create and update for site-to-site, remote-access, clients, and peers are payload-driven: build the JSON with --from-file (see the examples/ templates). Sensitive material such as WireGuard private keys and IPsec pre-shared keys is redacted in both get and create output; reconstruct those fields explicitly in update payloads if the controller requires them unchanged. The full walkthrough lives on the VPN page.
πSettings
unifly settings list # All site setting sections
unifly settings get dpi # One section
unifly settings set dpi enabled true # Patch one field
unifly settings set usg --data '{"mss_clamp": "auto"}' # Merge a JSON object
unifly settings export # Full JSON dump of every section
Site-level settings live in Session API setting sections. set performs a read-modify-write of the whole section, and get masks x_-prefixed secret fields in table mode (-o json shows everything). Session-gated: needs an API key on UniFi OS or session credentials. Details on the Site Settings page.
πCloud (Site Manager)
unifly cloud hosts # Consoles visible to the API key
unifly cloud sites # Sites across the fleet
unifly cloud devices # Devices across all consoles
unifly cloud devices --host <ID> # Scope to one console
unifly cloud isp # ISP metrics
unifly cloud sdwan # SD-WAN configs
unifly cloud switch <SITE> # Point the cloud profile at a site
cloud talks directly to the Site Manager fleet API at api.ui.com with a Site Manager API key; no controller connection is involved. With auth_mode = "cloud", regular Integration-backed commands (networks list, firewall policies list, β¦) tunnel through the cloud connector to one console. Set up with unifly config cloud-setup; the full story is on the Cloud & Site Manager page.
πOther Commands
unifly topology # Network tree visualization
unifly radius profiles # List RADIUS profiles
unifly wans list # List WAN interfaces
unifly sites list # List sites
unifly sites create --name "Branch Office" # Create site
unifly sites delete <NAME> # Delete site
unifly countries # Country codes for WiFi regulatory
πRaw API
Escape hatch for any controller endpoint. Routes through the Session client with automatic CSRF handling.
unifly api api/s/default/stat/sitedpi # GET a session endpoint
unifly api v2/api/site/default/nat # GET a v2 endpoint
unifly api api/s/default/stat/stadpi -m POST -d '{"type":"by_app"}' # POST
unifly api api/s/default/set/setting/teleport -m PUT -d '{"enabled":true}' # PUT
unifly api integration/v1/sites/<site-id>/hotspot/vouchers/<id> -m DELETE # DELETE
πConfiguration
unifly config init # Interactive setup wizard
unifly config cloud-setup # Guided Site Manager (cloud) profile
unifly config show # Show resolved config
unifly config set auth_mode hybrid # Set a config value
unifly config set-password # Store password in keyring
unifly config set-password --profile office # For a specific profile
unifly config profiles # List profiles (* = active)
unifly config use <PROFILE> # Switch default profile
Valid config set keys: controller, site, auth_mode, api_key, api_key_env, host_id, host_id_env, username, insecure, timeout, ca_cert. auth_mode accepts integration, session, hybrid, or cloud (legacy is normalized to session).
π--from-file / -F
Most create/update commands accept -F <file.json> to read the request body from a JSON file. This is the preferred approach for complex payloads.
Accepted by: networks, wifi, firewall policies, firewall zones, firewall groups, nat policies, acl, dns, traffic-lists, vpn site-to-site, vpn remote-access, vpn clients, vpn peers, vpn settings patch, and devices port-set (JSONC for switch port config-as-code).
JSONC is accepted everywhere: comments and trailing commas are stripped before parsing.
unifly networks create -F network.json
unifly firewall policies create -F policy.json
See examples/ for payload templates.
πList Filtering (--filter)
--filter on list commands is evaluated client-side and supports exactly one expression, with three operators:
unifly devices list --filter "state.eq('Online')"
unifly clients list --filter "name.contains('ring')"
unifly networks list --filter "vlan.in('20','30','40')"
Field paths address the JSON output shape (dot notation for nesting). An unparseable expression matches nothing and exits 0, so a silent empty result usually means a typo in the filter, not an empty collection.
The full server-side Integration filter DSL (neq, gt/lt, startswith, &&/||) applies only to hotspot purge --filter, which passes the expression to the controller.
πCapturing Created IDs
Create commands print the created entity on stdout in the requested output format, with the human confirmation line on stderr. That makes ID capture a one-liner:
NET_ID=$(unifly networks create --name "IoT" --vlan 30 \
--management gateway --ipv4-host "10.0.30.1/24" -o json | jq -r '.id')
# -o plain emits just the new ID
ZONE_ID=$(unifly firewall zones create --name "IoT Zone" -o plain)
sites create is the exception: the controller returns no record to print. VPN create output has sensitive fields (private keys, PSKs) redacted, same as get.
πGlobal Flags
-p, --profile <NAME> Controller profile to use
-c, --controller <URL> Controller URL (overrides profile)
-s, --site <SITE> Site name or UUID
-o, --output <FORMAT> Output: table, json, json-compact, yaml, plain
-k, --insecure Accept self-signed TLS certs (--insecure=false forces verification)
-v, --verbose Increase verbosity (-v, -vv, -vvv)
-q, --quiet Suppress non-error output
-y, --yes Skip confirmation prompts
--timeout <SECS> Request timeout (default 30, profiles may override)
--color <MODE> Color: auto, always, never
--no-cache Force fresh login (bypass session cache)
--api-key <KEY> Integration API key (one-shot override)
--insecure is tri-state: absent defers to the profile and [defaults], -k / --insecure accepts self-signed certificates, and --insecure=false forces verification no matter what the config says. The explicit value requires the equals form (--insecure false does not parse). --timeout has no baked-in flag default; when the flag and UNIFI_TIMEOUT are absent, the profileβs timeout wins, then [defaults], then the built-in 30 seconds.
πOutput Formats
| Format | Flag | Best For |
|---|---|---|
| Table | -o table | Human reading (default) |
| JSON | -o json | Scripting, agent use |
| Compact JSON | -o json-compact | Line-oriented processing, pipes |
| YAML | -o yaml | Config-style output |
| Plain | -o plain | IDs for xargs pipelines |
# Pipe plain IDs into another command
unifly clients list -o plain | xargs -n1 unifly clients get
πNext Steps
- TUI Dashboard: real-time monitoring with keybindings
- Authentication: which auth mode enables which commands
- Configuration: profiles, environment variables, precedence
- VPN, Switch Ports, Site Settings, Cloud & Site Manager: feature deep-dives
- Troubleshooting: common errors and fixes