Authentication & Transport — UniFi¶
API key¶
Both UniFi Network and UniFi Protect integration APIs authenticate with the same header:
X-API-KEY: <key>
The key is created in each application's Integrations section (UniFi OS), and Network and Protect mint separate keys — a Network key does not authenticate Protect, and vice versa. Over the local transport you therefore need each app's own key; over the remote transport a single account-level Site-Manager key reaches both apps through the connector.
Per-app keys in the CLI¶
Because the keys differ, the CLI resolves a key per app, with this precedence (highest first):
- App-specific flag —
--network-api-key/--protect-api-key - App-specific env —
UNIFI_NETWORK_API_KEY/UNIFI_PROTECT_API_KEY - Shared flag —
--api-key - Shared env —
UNIFI_API_KEY
Setting both UNIFI_NETWORK_API_KEY and UNIFI_PROTECT_API_KEY (e.g. in one .env) lets a single
configuration drive unifi network … and unifi protect … without swapping keys. Supplying only
the shared UNIFI_API_KEY keeps the original single-key behaviour for whichever app you target.
Two transports¶
The SDK supports the two access modes UniFi documents. Both differ only by base URL; the auth
header and the /v1/... operation paths are identical.
Local (per-console)¶
https://{host}/proxy/{app}/integration/v1/...
{host}— the console's address (IP or hostname).{app}—networkorprotect.- Example:
curl -X GET "https://$UNIFI_HOST/proxy/network/integration/v1/info" \ -H "X-API-KEY: $UNIFI_API_KEY"
Local consoles typically present a self-signed TLS certificate, so the SDK must allow relaxed or custom TLS verification (see TLS options below).
Remote (cloud connector)¶
https://api.ui.com/v1/connector/consoles/{consoleId}/{app}/integration/v1/...
{consoleId}— the console identifier in the UniFi cloud.- Example:
curl -X GET "https://api.ui.com/v1/connector/consoles/$CONSOLE_ID/network/integration/v1/info" \ -H "X-API-Key: $UNIFI_SM_KEY"
api.ui.com presents a normal publicly-trusted certificate; no TLS relaxation is needed.
SDK surface¶
// Local console (self-signed cert)
c := unifi.Local("192.168.1.1", apiKey, unifi.WithInsecureSkipVerify())
// Remote via cloud connector
c := unifi.Remote(consoleID, apiKey)
// Latest pinned version, generated client + types:
net, err := c.Network()
if err != nil { /* handle */ }
info, err := net.GetInfoWithResponse(ctx)
// A specific coexisting version (e.g. when pinning to an exact release):
old, err := networkv10_3_58.NewClientWithResponses(
c.NetworkBaseURL(),
networkv10_3_58.WithRequestEditorFn(c.RequestEditor()),
networkv10_3_58.WithHTTPClient(c.HTTPClient()),
)
Options¶
| Option | Effect |
|---|---|
WithHTTPClient(*http.Client) |
Use a caller-supplied client (proxies, transports, instrumentation). |
WithTimeout(d) |
Per-request timeout on the default client. |
WithUserAgent(s) |
Override the User-Agent. |
WithInsecureSkipVerify() |
Skip TLS verification — for local self-signed consoles only. |
WithRootCAs(*x509.CertPool) |
Trust a specific CA (e.g. a pinned console cert). |
WithTLSConfig(*tls.Config) |
Full control over TLS. |
WithInsecureSkipVerify is documented as local-only and emits guidance against use over the
remote transport.
Request flow¶
Local/Remotebuild aConnwith the resolved base-URL prefix and a configured*http.Client.Conn.RequestEditor()returns aRequestEditorFnthat setsX-API-KEYon every outgoing request.- Generated clients are constructed with
(baseURL, WithRequestEditorFn(editor), WithHTTPClient(...)). - WebSocket subscriptions reuse the same header + TLS config via
Conn.Subscribe.
See ADR-0002.