Skip to content
Development
Skill

/unifi-connect

Use when connecting an agent to a UniFi gateway (UDM Pro, UDM SE, Cloud Gateway) for the first time, or when API calls to one are failing: empty response bodies, curl returning HTTP 000, 401 on a key that works elsewhere, "how do I get a UniFi API key", "SSH is closed on my

From plugin
unifi
455 skills

Claude Code

$ npx -y skills add t3chnaztea/unifi-skills --skill unifi-connect --agent claude-code

SKILL.md

unifi-connect.SKILL.md
name: unifi-connect
description: >-
  Use when connecting an agent to a UniFi gateway (UDM Pro, UDM SE, Cloud
  Gateway) for the first time, or when API calls to one are failing: empty
  response bodies, curl returning HTTP 000, 401 on a key that works elsewhere,
  "how do I get a UniFi API key", "SSH is closed on my UDM", "connect to
  UniFi", "talk to my UniFi controller". Covers minting an API key over the
  API, which endpoint families accept a key, the cookie-session fallback, the
  HTTP/2 empty-body trap, the endpoint map, and the safety doctrine: dry-run,
  read-only mode, snapshot-before-mutate rollback, and the audit trail. Start
  here: the other skills assume this one. Not for firewall policy (unifi-firewall), Wi-Fi and radios
  (unifi-wifi), client and port operations (unifi-clients).
compatibility: >-
  UniFi OS gateways running a self-hosted Network controller. Verified on
  UniFi OS 5.1.19 / Network 10.4.57. Endpoint paths and auth behavior are
  version-sensitive; confirm against your own controller.

UniFi Connect

The first thing to know: **SSH is usually closed and you do not need it.** UniFi OS exposes a full REST API on the same host as the web UI, and everything these skills do goes through it. The second thing: **UniFi has three overlapping API surfaces with different auth rules**, and picking the wrong one produces errors that look like broken credentials when they are not.

Throughout, `<UDM_HOST>` is your gateway's LAN address. Never hardcode it into a file you might share.

Lane 1: API key (use this)

API keys are the modern lane. No login round-trip, no cookie jar, no CSRF token, and they sidestep the HTTP/2 bug described below.

Minting a key over the API

The admin UI has a key page, but you do not need it. Keys are mintable from an authenticated session:

# Log in once to get a session
curl -sk -X POST "https://<UDM_HOST>/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"<ADMIN_USER>","password":"<ADMIN_PASS>"}' \
  -c /tmp/unifi_cookies -D /tmp/unifi_headers

CSRF=$(grep -i 'x-updated-csrf-token' /tmp/unifi_headers | awk '{print $2}' | tr -d '\r')

# Mint a named key
curl -sk --http1.1 -b /tmp/unifi_cookies -H "x-csrf-token: $CSRF" \
  -H "Content-Type: application/json" \
  -X POST "https://<UDM_HOST>/proxy/users/api/v2/user/self/keys" \
  -d '{"name":"agent"}'

The response contains the key **once**. Store it and move on. Give the agent its own named key rather than sharing yours: named keys are individually revocable, and when something writes a policy you did not expect you want to know which identity did it.

The same path answers `GET`, which lists existing keys with `id`, `name`, `masked_api_key`, timestamps, and the key's `permissions` map. Useful for confirming a key exists without minting another, and for auditing what is out there:

curl -sk -H "X-API-Key: $UNIFI_API_KEY" \
  "https://<UDM_HOST>/proxy/users/api/v2/user/self/keys"

**Read that `permissions` map once.** A key minted by an admin account inherits that account's rights across every UniFi application on the box, Network and Protect and the rest, not just the one you meant to automate. There is no "read-only Network" key by default. So: create a dedicated limited admin account and mint the key as that account rather than as your own super-admin, and treat the key as equivalent to the password of whoever minted it.

Using it

export UNIFI_API_KEY="..."   # from an env file, never committed, never in a skill

curl -sk -H "X-API-Key: $UNIFI_API_KEY" \
  "https://<UDM_HOST>/proxy/network/api/s/default/stat/device"

Self-signed cert on the gateway is normal, hence `-k`. If that bothers you, pin the gateway's cert rather than disabling verification.

What a key can and cannot reach

This matrix is the single most useful thing on this page. A key that works perfectly for twenty calls and then 401s is not a broken key:

| Surface | Base path | API key? | |---|---|:---:| | Network, legacy | `/proxy/network/api/s/default/...` | yes | | Network, v2 | `/proxy/network/v2/api/site/default/...` | yes | | Protect, integration API | `/proxy/protect/integration/v1/...` | yes | | **Protect, legacy API** | `/proxy/protect/api/...` | **no, 401** | | UniFi OS system | `/api/system` | yes |

The legacy Protect API (`bootstrap`, `events`, the older `cameras` endpoint) is the only reason Lane 2 still exists. If you are not reading Protect internals, you never need a cookie.

Lane 2: cookie session (only for legacy Protect)

curl -sk -X POST "https://<UDM_HOST>/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"<API_USER>","password":"<API_PASS>"}' \
  -c /tmp/unifi_cookies -D /tmp/unifi_headers

CSRF=$(grep -i 'x-updated-csrf-token' /tmp/unifi_headers | awk '{print $2}' | tr -d '\r')

curl -sk --http1.1 -b /tmp/unifi_cookies -H "x-csrf-token: $CSRF" \
  "https://<UDM_HOST>/proxy/protect/api/bootstrap"

Every non-GET also needs `-H "Content-Type: application/json"`.

The HTTP/2 empty-body trap

Worth its own section because it burns hours and looks like an auth failure.

**With cookie-session auth, every `/proxy/*` endpoint returns an empty body over HTTP/2, even with correct cookies and CSRF token.** `curl -w "%{http_code}"` reports `000`. The same call with `--http1.1` returns full JSON immediately.

The tell is that `/api/auth/login` itself works fine either way, so login succeeds, you conclude auth is working, and then every subsequent call silently returns nothing. It affects Network and Protect proxy paths alike.

  • **Cookie-session auth: always pass `--http1.1` on `/proxy/*`.** Treat it as

mandatory, not situational.

  • **API-key requests are immune.** Verified: plain HTTP/2 with `X-API-Key`

returns full bodies. This is one more reason Lane 1 is the default.

If your client library hides the HTTP version from you and cookie auth returns empty bodies, that is this bug. For

Read more
@t3chnaztea
Ships withunifi

Agent skills for administering a real UniFi network over its local API: auth, zone firewall, Wi-Fi, clients, and the site map.

Stars on GitHub

Momentum

stars in total
45
Star history of t3chnaztea/unifi-skills on GitHub, a chart by star-history.com

Other skills on unifi.

unifi-clients

unifi-clients

Use when operating on UniFi clients, devices, switch ports, or DHCP: "block a device", "kick a client off wifi", "restart an…

@t3chnaztea@t3chnazteaInstall Skill
unifi-context-map

unifi-context-map

Use when an agent keeps guessing wrong about a UniFi network, when starting recurring agent work against a gateway, or when asked…

@t3chnaztea@t3chnazteaInstall Skill
unifi-firewall

unifi-firewall

Use when working on UniFi firewall rules, zones, or network segmentation: "my firewall rules are empty", "rest/firewallrule…

@t3chnaztea@t3chnazteaInstall Skill
unifi-wifi

unifi-wifi

Use when UniFi Wi-Fi is slow, unstable, or being tuned: "my wifi is slow but speedtest on the router is fast", "great signal,…

@t3chnaztea@t3chnazteaInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about unifi-connect.

Which coding agents can use unifi-connect?
unifi-connect installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.