This is github.com/unpoller/unifi/v5: a Go library that connects to a Ubiquiti UniFi controller and pulls data (clients, devices, sites, alarms, events, etc.). It does not update or change controller settings by design.
Entry point: unifi.NewUnifi(config *Config) → authenticated *Unifi client.
Typical usage flow: Config → NewUnifi(config) → GetSites() → GetClients(sites) / GetDevices(sites). Optionally GetAlarms, GetEvents, GetAnomalies, etc.
Returns: []*Site, []*Client, *Devices (with UAPs, USWs, USGs, UDMs, UXGs, PDUs, UBBs, UCIs), plus alarms, events, DPI, traffic. Data is unmarshaled into large structs for consumption.
- Linter:
.golangci.yaml–nlreturn,revive,tagalign,testpackage,wsl_v5. Max issues 0;fix: true. - wsl_v5: Use blank lines between logical blocks; keep
if/forbodies short. - Tests: Use
package unifiwith// nolint: testpackagewhere needed. Prefert.Parallel(),assert/requirefromgithub.com/stretchr/testify. Mock viaUnifiClientandmocks.MockUnifi. - Errors: Wrap with
fmt.Errorf("context: %w", err). Use package sentinels (ErrAuthenticationFailed, etc.). - Imports: Group stdlib, then third-party.
Run golangci-lint run and go test ./... before committing.
Authentication: Cookie-based via /api/login (standard) or /api/auth/login (UDM Pro). Alternative: API key via X-API-Key header. Library handles both via Config.User/Config.Pass or Config.APIKey.
Endpoint pattern: /api/s/{site}/... where {site} is typically "default". UDM Pro requires /proxy/network prefix.
Response format: {"data": [...], "meta": {"rc": "ok"}}. Errors: {"data": [], "meta": {"msg": "api.err.LoginRequired", "rc": "error"}}. Handle meta.count for truncated results.
Key endpoints (constants in types.go):
/api/s/{site}/stat/device- Devices/api/s/{site}/stat/sta- Active clients/api/s/{site}/stat/event- Events/api/s/{site}/list/alarm- Alarms/api/s/{site}/stat/stadpi- Client DPI stats/api/s/{site}/stat/sitedpi- Site DPI stats/api/s/{site}/stat/anomalies- Anomalies
Code patterns:
- Use
u.GetData(apiPath, &response)for GET requests - API paths use
fmt.Sprintf(APIDevicePath, site.Name)etc. - Most fetches are per-site:
GetSites()first, then loopGetDevices(sites),GetClients(sites), etc. - Single-site helpers like
GetUAPs(site)also exist GetDevicesreturns*Deviceswith device slices (UAPs, USWs, USGs, UDMs, UXGs, PDUs, UBBs, UCIs)- Parsing uses
parseDeviceswithjson.RawMessageand type detection
Base URL: https://api.ui.com/v1/
Authentication: API key in X-API-Key header. Currently read-only.
Rate limits: Early Access (EA): 100 requests/minute; v1 stable: 10,000 requests/minute.
Implementation: See remote.go (RemoteAPIClient). Used for discovering consoles and sites managed via UniFi Site Manager (cloud).
- Package layout: Single package
unififor core logic.main/for CLI.mocks/implementsUnifiClientfor testing. - UnifiClient: Interface in
types.go; both*Unifiandmocks.MockUnifiimplement it. Use it for dependency injection. - Config:
ConfighasURL,User,Pass, optionalAPIKey,ErrorLog/DebugLog,SSLCert,VerifySSL. - Logger:
ErrorLog/DebugLogaccept(format, args...); uselog.Printfor custom.
When adding features:
- Follow existing patterns (e.g.
GetDevices/GetClients) - Use
GetDatafor HTTP requests - Add tests following existing test patterns
- For new device/client types: extend
DevicesandparseDevices, add getters followingGetUAPs/GetUSWsstyle, and update mocks - Implement all
UnifiClientinterface methods when adding mocks or new client types - Check with
var _ unifi.UnifiClient = &YourClient{}