A Rust API library for UniFi Network controllers, with optional support for the UniFi Protect Integration API.
use rustifi::UnifiClient;
#[tokio::main]
async fn main() -> rustifi::Result<()> {
// Create a client with strict TLS validation (recommended)
let client = UnifiClient::with_api_key(
"https://unifi.example.com",
"your-api-key"
)?;
// Fetch all sites
let sites = client.request::<rustifi::api::sites::GetSites>().await?;
for site in sites.data {
println!("Site: {} ({})", site.name, site.id);
}
Ok(())
}By default, rustifi uses strict TLS validation and requires valid certificates.
Use the standard constructors:
// These require valid TLS certificates
let client = UnifiClient::new("https://unifi.example.com")?;
let client = UnifiClient::with_api_key("https://unifi.example.com", "api-key")?;Many local UniFi controllers use self-signed certificates. For these, use the _insecure variants:
// WARNING: Only use for local controllers on trusted networks
let client = UnifiClient::new_insecure("https://192.168.1.1")?;
let client = UnifiClient::with_api_key_insecure("https://192.168.1.1", "api-key")?;Security Warning: The
_insecuremethods disable TLS certificate validation, which makes connections vulnerable to man-in-the-middle attacks. Only use these methods for local controllers on trusted networks.
unifi(default) — the UniFi Network controller API (UnifiClient).protect— the official UniFi Protect Integration API (ProtectClient).
# Network only (default)
rustifi = "2"
# Network + Protect
rustifi = { version = "2", features = ["protect"] }
# Protect only
rustifi = { version = "2", default-features = false, features = ["protect"] }The protect feature wraps the official Protect Integration API (Protect >= 5.3),
served at https://{console}/proxy/protect/integration/v1. Generate an API key in
the Protect app under Settings -> Control Plane -> Integrations.
use rustifi::protect::ProtectClient;
#[tokio::main]
async fn main() -> rustifi::Result<()> {
// Local consoles usually have self-signed certificates, so the
// `_insecure` constructor is common here (trusted networks only).
let client = ProtectClient::new_insecure("https://192.168.1.1", "your-api-key")?;
// List cameras and save a snapshot
for camera in client.cameras().await? {
println!("Camera: {} ({:?})", camera.name, camera.state);
}
let jpeg = client.snapshot("camera-id", true).await?;
std::fs::write("snapshot.jpg", jpeg)?;
Ok(())
}Motion, smart-detection, doorbell, and connectivity events are delivered over a WebSocket (the Integration API has no REST event-history endpoint). The stream ends on disconnect and there is no replay cursor, so reconnect in a loop:
use futures::StreamExt;
loop {
let mut stream = match client.subscribe_events().await {
Ok(stream) => stream,
Err(e) => {
eprintln!("subscription failed: {e}");
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
continue;
}
};
while let Some(msg) = stream.next().await {
match msg {
Ok(event) => println!("{:?} {:?}", event.action, event.item.event_type),
Err(e) => eprintln!("stream error: {e}"),
}
}
// Events that occur while disconnected are lost.
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
}subscribe_device_updates() provides the same envelope for partial device-state
patches. Not yet covered: PTZ, talkback, liveviews, file uploads, chime play,
and alarm-manager webhooks.
- Implement some access points
- Implement some switches
- Ensure compliance with Rust API Guidelines Checklist, Including traits
- Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Display, Default
- From, TryFrom, AsRef, AsMut
- Errors
- Link capacity on uplinks
- Tests
- Documentation
- Examples
- Devices
- Basic Information
- Get
- Update
- AP
- Group
- Model
- Name
- Radio
- Channel
- Width
- Power
- Meshing
- Number of Clients
- CPU
- Memory
- SW
- Name
- Model
- Port
- Number
- Type
- Status
- Uptime
- Bytes
- Packets
- Dropped
- Errors
- Native VLAN
- Allowed VLANs
- Port Isolation
- CPU
- Memory
- Basic Information
- Clients
- Type
- Impose Punishment
- Ban
- WiFi
- Network
- UX
- NanoHD
- U7-Pro
- U7-Pro-Max
- U6-Mesh
- UWB-XG
- UAP-XG
- AC-Mesh
- AC-Mesh-Pro
- AC-Pro
- USW-Pro-Aggregation
- USW-Aggregation
This project is licensed under GNU General Public License v2.0 (GPL-2.0-only).