Chrison.UnifiSharp.Cli 0.1.0

dotnet tool install --global Chrison.UnifiSharp.Cli --version 0.1.0
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Chrison.UnifiSharp.Cli --version 0.1.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Chrison.UnifiSharp.Cli&version=0.1.0
                    
nuke :add-package Chrison.UnifiSharp.Cli --version 0.1.0
                    

UnifiSharp

NuGet Downloads ci built with Fallout License: MIT

A C# client for the UniFi Network API โ€” mostly code-generated from Ubiquiti's official OpenAPI spec, with a thin hand-written runtime for auth and transport. Sibling to ProxmoxSharp; built to bring the UniFi-managed network under the homelab's C#-native IaC. See ADR-0003.

dotnet add package Chrison.UnifiSharp

Approach

flowchart LR
  SPEC["๐Ÿ“œ UniFi OpenAPI 3.1<br/>(console / beezly mirror)"] --> KIOTA["โš™๏ธ Kiota (pinned tool)<br/>generate C# client"]
  KIOTA --> API["๐Ÿ“ฆ UnifiSharp.Api<br/>generated ยท tracks UniFi release"]
  API --> RT["โœ๏ธ UnifiSharp<br/>hand-written runtime (X-API-KEY)"]
  RT --> LEG["๐Ÿงฉ UnifiSharp.Legacy<br/>write adapter ยท API-key or session<br/>(port-forwards ยท firewall ยท networks ยท clients)"]
  classDef gen fill:#e0e7ff,stroke:#4f46e5;
  class API gen;

The UniFi spec is already OpenAPI 3.1, so โ€” unlike ProxmoxSharp โ€” there's no converter; Kiota consumes it directly. The generated client is regenerated on build (only when the spec changes) and not committed.

Write coverage caveat (per ADR-0003): the official API is read-mostly today (firewall rules / port profiles not yet exposed; full write rolling out through 2026). Those will be filled by a thin, deletable legacy adapter later. This repo starts read-only.

Projects & versioning

Project What Version
src/UnifiSharp.Api/ Kiota-generated client. Generated/ produced on build (gitignored). Tracks the UniFi Network API release (e.g. 10.4.57).
src/UnifiSharp/ Hand-written runtime (UnifiApi, X-API-KEY auth, options) over .Api. Independent SemVer (0.1.0).
tests/UnifiSharp.Tests/ Unit tests. โ€”

Build

Built with Fallout (Chris's C#/.NET build system, a NUKE successor). Targets: Compile โ†’ Test โ†’ Pack โ†’ Publish.

./build.sh              # default: Test (Compile regenerates UnifiSharp.Api from the spec, then compiles)
./build.sh Pack         # produce the Chrison.* nupkgs into artifacts/

Requires the .NET 10 SDK (see global.json) and GITHUB_PACKAGES_PAT in the environment (a PAT with read:packages on the Fallout-build org โ€” the build restores Fallout.* from that feed, see nuget.config). CI runs ./build.sh Test on push/PR.

Use it

var client = UnifiApi.Create(new UnifiClientOptions
{
    // NOTE: no /v1 โ€” the generated client appends the version segment itself.
    // UniFi OS (Cloud Gateway/UDM/UniFi OS Server):  https://<host>/proxy/network/integration
    // Standalone Network Application:                 https://<host>:8443/integration
    BaseUrl = new Uri("https://192.168.1.1/proxy/network/integration"),
    ApiKey  = "<local API key โ€” Settings โ†’ Integrations>",
    VerifyTls = false,   // self-signed LAN cert
});
// read endpoints: sites, networks, WLANs, firewall zones, devices, clients โ€ฆ

Base-URL note (verified 2026-05-31 against the .containers/unifi UniFi OS Server container): set BaseUrl to the integration root without /v1 โ€” the client adds /v1/โ€ฆ. UniFi OS exposes it under /proxy/network/integration; a standalone Network Application omits that prefix (/integration).

Packages

Published to nuget.org (public) under the Chrison.* prefix, via Trusted Publishing (OIDC โ€” no stored API key): Chrison.UnifiSharp, Chrison.UnifiSharp.Api, Chrison.UnifiSharp.Cli. Prerelease on push to main (โ€ฆ-preview.N), stable on a v* tag. .Api tracks the UniFi API release; the library its own SemVer. IDs use the Chrison.* prefix because the bare UnifiSharp ID is taken on nuget.org by an unrelated project; assembly names and namespaces stay UnifiSharp, so using UnifiSharp; is unchanged.

Refresh the spec (new UniFi release)

Pull the OpenAPI for the controller's version from the console (Settings โ†’ Integrations) or the beezly/unifi-apis mirror into src/UnifiSharp.Api/schema/, update the filename + VersionPrefix, rebuild.

CLI (unifisharp)

A dotnet global tool over the library:

export UNIFI_BASE_URL="https://localhost:8443/proxy/network/integration/v1"
export UNIFI_API_KEY="โ€ฆ"  UNIFI_VERIFY_TLS=false
unifisharp sites       # list sites
unifisharp discover    # JSON snapshot: sites + networks/WLANs/firewall/devices/clients
unifisharp networks    # networks/VLANs per site (name, vlan id, purpose, enabled)
unifisharp wlans       # WLANs/SSIDs per site (ssid, enabled, security)
unifisharp firewall    # firewall zones, policies, and ACL rules per site
unifisharp devices     # adopted devices per site (name, model, ip, mac, firmware, state)
unifisharp clients     # connected clients per site (name, type, ip, connectedAt)

Legacy adapter auth

UnifiLegacyOptions takes either credential, and TryFromEnvironment() prefers the key:

Mode Set Notes
API key UNIFI_API_KEY + (UNIFI_LEGACY_BASE_URL or UNIFI_LOCAL_HOST) X-API-KEY on every request โ€” no login, cookie or CSRF token. Preferred against a real gateway; the same key the integration API uses.
Session UNIFI_USERNAME + UNIFI_PASSWORD + base URL POST /api/auth/login. The only mode the .containers/unifi test container supports, since it can't mint API keys.

With UNIFI_LOCAL_HOST alone the site URL is derived as https://<host>/proxy/network/api/s/default.

The destructive live tests (UnifiLegacyLiveTests โ€” they create and delete a port-forward, a firewall group and a VLAN) are gated on session auth on purpose, so a shell holding only an API key can never point them at a production gateway. Read-only live checks (UnifiLegacyReadOnlyLiveTests) run in either mode.

Status

Read client + discover + unifisharp CLI building from the 10.4.57 spec. Live read tests skip without UNIFI_* โ€” run them against the .containers/unifi test controller (never the live network). Next: the legacy write adapter (firewall rules / port profiles) once verified against the container.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.1.0 128 8/16/2026
0.1.0-preview.8 66 8/16/2026
0.1.0-preview.6 65 8/16/2026
0.1.0-preview.5 72 8/3/2026
0.1.0-preview.4 70 7/24/2026
0.1.0-preview.3 69 7/23/2026
0.1.0-preview.2 71 7/23/2026
0.1.0-preview.1 59 7/23/2026