Skip to content

Add UniFi Protect API Key Only connection mode - #2132

Open
nberardi wants to merge 3 commits into
koush:mainfrom
nberardi:cursor/unifi-protect-api-key-935a
Open

Add UniFi Protect API Key Only connection mode#2132
nberardi wants to merge 3 commits into
koush:mainfrom
nberardi:cursor/unifi-protect-api-key-935a

Conversation

@nberardi

@nberardi nberardi commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an API Key Only connection mode to the UniFi Protect plugin, alongside the existing local user account flow — modeled after Home Assistant’s approach in home-assistant/core#176410.

Connection modes

Mode Auth Scope
Local User (default) Username / password against the private Protect API Full feature set (unchanged)
API Key Only UniFi OS Integration API key (X-API-KEY) against the public Integration API Cameras + lights

API keys are created in the UniFi OS local portal under Settings → Control Plane → Integrations.

API Key Only capabilities

  • Cameras: RTSPS streams, snapshots, motion/smart detections, doorbell ring, status LED
  • Lights: on/off, brightness, PIR motion
  • Public events/devices websockets for realtime updates

Not available in API Key Only (use Local User)

  • Sensors and locks
  • Two-way audio / intercom
  • Privacy masks, dynamic bitrate, optical zoom
  • Fingerprint sensors and package-camera snapshots

Implementation notes

  • New ProtectPublicApi client (plugins/unifi-protect/src/public-api.ts) talks to /proxy/protect/integration/v1/*
  • Public camera/light payloads are adapted into bootstrap-compatible shapes so discovery and device helpers can be shared
  • Settings UI shows username/password or API key based on the selected mode
  • Existing Local User installs are unaffected (default mode)
  • Public API client rate-limits to UniFi’s 10 req/s window, retries 429s, and safely resets CONNECTING websockets
  • Version bumped to 0.2.0

Test plan

  • API Key Only connects with IP + API key against Protect 7.2.x
  • Fixed 429 / websocket uncaughtException loop on bootstrap (rate limit + safe WS reset)
  • Local User username/password path still connects and streams
  • Discover/adopt cameras; verify RTSPS playback and snapshots
  • Motion / smart detect / doorbell ring events update Scrypted sensors
  • Lights on/off and brightness work
  • Sensors/locks are not offered in API Key Only mode
  • Switching back to Local User still works with stored credentials

cursoragent and others added 3 commits September 3, 2026 17:25
Support authenticating with a UniFi OS Integration API key via the
public Protect Integration API, similar to Home Assistant's API-key-only
mode, while keeping the existing local user account path.

API Key Only currently covers cameras (RTSPS streams, snapshots,
detections) and lights; sensors, locks, intercom, privacy masks, and
dynamic bitrate remain local-user features.

Co-authored-by: Nick Berardi <me@nickberardi.com>
The API-key-only path was calling getBootstrap twice after login, which
exceeded UniFi's 10 req/s public Integration API limit and returned 429.
A failed second bootstrap then reset still-connecting websockets; closing
a CONNECTING ws emits an error with no listener and crashed the plugin.

- Bootstrap only once after login
- Rate-limit and retry public API requests on 429
- Fetch cameras/lights sequentially; prime RTSPS with GET-only at bootstrap
- Safely terminate CONNECTING websockets on reset

Co-authored-by: Nick Berardi <me@nickberardi.com>
Co-authored-by: Nick Berardi <me@nickberardi.com>
@koush

koush commented Sep 4, 2026

Copy link
Copy Markdown
Owner

I think this is fine to have sitting around in case they ever break their undocumented API, but it's generally unnecessary imo. too much breakage. its more compelling if they actually offer everything their undocumented api supports that we need.

image

@nberardi

nberardi commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

The reason I created this was primarily selfish:

  1. The UniFi Fabric Identity SSO was making it increasingly complex to manage and create local only accounts.

  2. The private API doesn’t work with Fabric managed users.

  3. HA recently moved in a similar dual support direction in their 2026.9 release, and I wanted to stay pace with the API changes for Scrypted.

In regards to your comments, yes the public Integration API still doesn’t cover everything Scrypted needs, primarily PTZ, so Local User remains the full-featured default in the configuration.

This PR keeps that path unchanged and adds API Key Only as an optional mode for the subset the public API does support today (steams, snapshots, lights).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants