Find UniFi devices on your network and adopt them to a controller from the command line. No clicking through controller UIs, no browser required.
Works with any UniFi controller on its own, or with Tamarack if you're managing a fleet.
# Homebrew (macOS / Linux)
brew install tamarackcloud/tap/tamarack
# Go
go install github.com/tamarackcloud/tamarack-cli/cmd/tamarack@latest
Pre-built binaries for Linux, macOS, and Windows (amd64 and arm64) are on the releases page.
Scan your network for unadopted UniFi devices:
tamarack discover
MAC IP MODEL HOSTNAME FIRMWARE
78:8a:20:86:5e:0b 192.168.1.20 UAP-AC-Pro Office-AP 6.5.28
aa:bb:cc:dd:ee:ff 192.168.1.21 USW-24-PoE Switch-1 6.5.59
2 device(s) found.
Adopt them to your controller:
tamarack setup --inform-url http://controller:8080/inform
This SSHs into each device using factory defaults (ubnt/ubnt) and runs set-inform. You get a confirmation prompt per device, or pass --auto to skip it.
No account needed.
If you're on the Tamarack platform, use controller names instead of URLs:
tamarack login
tamarack controllers # list your controllers
tamarack setup --controller my-controller # discover + adopt
tamarack diagnose --controller my-controller # DNS, HTTPS, and inform connectivity checks
The tool sends a UDP broadcast on port 10001 (the Ubiquiti discovery protocol) across all local interfaces and collects responses.
Only unadopted (factory-default) devices respond. If a device is already adopted to a controller, it won't show up.
By default, discovery broadcasts on all active interfaces. You can target specific subnets instead:
tamarack discover --subnet 192.168.1.0/24
tamarack discover --subnet 10.0.1.0/24 --subnet 10.0.2.0/24
Subnet sweeps send a unicast packet to every host in the range, so devices behind switches that eat broadcast traffic still get found.
If you need to reach a device on a different subnet or VLAN:
tamarack discover --target 10.0.50.10
tamarack discover --subnet 192.168.1.0/24 --target 10.0.50.10
Default scan timeout is 5 seconds. Bump it for slow or remote networks:
tamarack discover --timeout 15s
Scan for unadopted UniFi devices.
tamarack discover [--subnet CIDR...] [--target IP...] [--timeout DURATION]
Discover devices and adopt them. Needs either --inform-url (standalone) or --controller (Tamarack platform).
# Standalone
tamarack setup --inform-url http://controller:8080/inform [--auto]
# Platform
tamarack setup --controller my-controller [--auto]
Adoption SSHs into each device and runs set-inform. Devices need to be in factory-default state (ubnt/ubnt credentials). Already-adopted devices or ones with changed credentials will be skipped with an error.
--auto skips the per-device confirmation prompt.
List all controllers across your teams. Requires auth.
tamarack controllers
Check DNS resolution, HTTPS, and inform URL reachability for a controller.
tamarack diagnose --controller my-controller
Store or remove an API key. Keys go in ~/.tamarack/config.json with 0600 permissions.
tamarack login # interactive prompt (input is hidden)
tamarack logout # deletes stored credentials
Generate an API key at app.tamarack.cloud/settings/api-tokens.
Self-update to the latest GitHub release.
tamarack upgrade
Print version, commit, and build date.
tamarack version
Token is resolved in this order:
--tokenflagTAMARACK_API_KEYenvironment variable~/.tamarack/config.json(written bytamarack login)
| Variable | Description |
|---|---|
TAMARACK_API_KEY |
API token |
TAMARACK_API_URL |
API base URL (default: https://api.tamarack.cloud) |
TAMARACK_SUBNET |
Default CIDR subnet(s) for discovery |
TAMARACK_TIMEOUT |
Default scan timeout |
All commands take --json:
tamarack discover --json | jq '.[] | .ip'
tamarack controllers --json
tamarack diagnose --controller my-controller --json
The discovery protocol parser is in pkg/ubiquiti and has no dependencies outside stdlib. If you're building your own UniFi tooling in Go, you can import it directly:
import "github.com/tamarackcloud/tamarack-cli/pkg/ubiquiti"
// Build a discovery request
pkt := ubiquiti.DiscoveryPacket() // 4-byte UDP payload for port 10001
// Parse a discovery response
device, err := ubiquiti.ParseResponse(buf)
// device.MAC, device.IP, device.Model, device.Hostname, device.Firmware, device.ESSID
// Network helpers
broadcast, _ := ubiquiti.BroadcastAddr("192.168.1.0/24") // 192.168.1.255
hosts, _ := ubiquiti.HostAddrs("192.168.1.0/30") // [192.168.1.1, 192.168.1.2]
MIT and Apache 2.0. See LICENSE.