{"id":31943078,"url":"https://github.com/uchkunrakhimow/unifi-best-practices","last_synced_at":"2026-02-18T03:03:21.571Z","repository":{"id":287261928,"uuid":"964152620","full_name":"uchkunrakhimow/unifi-best-practices","owner":"uchkunrakhimow","description":"Developer guide for the UniFi Controller API with concise endpoint docs, auth patterns, device/client control, statistics, WebSocket events, and code examples.","archived":false,"fork":false,"pushed_at":"2025-09-29T10:26:55.000Z","size":9,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-14T09:48:19.704Z","etag":null,"topics":["best-practices","documentation","unifi","unifi-api","unifi-controller-api"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/uchkunrakhimow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-10T19:11:21.000Z","updated_at":"2025-10-06T19:10:25.000Z","dependencies_parsed_at":"2025-09-29T12:32:21.637Z","dependency_job_id":null,"html_url":"https://github.com/uchkunrakhimow/unifi-best-practices","commit_stats":null,"previous_names":["uchkunrakhimow/unifi-controller-api-professional-guide","uchkunrakhimow/unifi-best-practices"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/uchkunrakhimow/unifi-best-practices","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchkunrakhimow%2Funifi-best-practices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchkunrakhimow%2Funifi-best-practices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchkunrakhimow%2Funifi-best-practices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchkunrakhimow%2Funifi-best-practices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uchkunrakhimow","download_url":"https://codeload.github.com/uchkunrakhimow/unifi-best-practices/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchkunrakhimow%2Funifi-best-practices/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29566671,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T00:47:08.760Z","status":"online","status_checked_at":"2026-02-18T02:00:09.468Z","response_time":162,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["best-practices","documentation","unifi","unifi-api","unifi-controller-api"],"created_at":"2025-10-14T09:47:54.696Z","updated_at":"2026-02-18T03:03:16.562Z","avatar_url":"https://github.com/uchkunrakhimow.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\" id=\"unifi-controller-api\"\u003e\nUniFi Controller API — Comprehensive Guide\n\u003c/h1\u003e\n\u003cdiv align=\"center\"\u003e\n    \u003cimg alt=\"License\" src=\"https://img.shields.io/badge/License-MIT-blue.svg\" /\u003e\n    \u003cimg alt=\"UniFi\" src=\"https://img.shields.io/badge/UniFi-API-0a84ff.svg\" /\u003e\n\u003c/div\u003e\n\nA comprehensive, high-level reference for developers working with the Ubiquiti UniFi Controller API.\n\n## 📚 Table of Contents\n\n- [UniFi Controller API — Comprehensive Guide](#unifi-controller-api)\n\n  - [Table of Contents](#table-of-contents)\n  - [Overview](#overview)\n  - [Core Concepts](#core-concepts)\n  - [Quick Start](#quick-start)\n  - [API Endpoint Reference](#api-endpoint-reference)\n\n    - [Authentication](#authentication)\n    - [Device Management](#device-management)\n    - [Client Management](#client-management)\n    - [Internet Access Control](#internet-access-control)\n    - [Network Configuration](#network-configuration)\n    - [Site Management](#site-management)\n    - [Statistics \u0026 Monitoring](#statistics--monitoring)\n    - [Pagination and Filtering](#pagination-and-filtering)\n\n  - [WebSocket API](#websocket-api)\n\n    - [Connection Establishment](#connection-establishment)\n    - [Common Event Types](#common-event-types)\n    - [WebSocket Event Handling Best Practices](#websocket-event-handling-best-practices)\n\n## 🧭 Overview\n\nThe UniFi Controller API allows programmatic control over your entire UniFi network, including devices, clients, and configuration settings. This document provides a structured guide to the most common and useful API endpoints.\n\n## 🧠 Core Concepts\n\n- **Authentication**: Session-based with cookie persistence\n- **Site Structure**: Most endpoints require a site identifier (`default` is the primary site)\n- **Response Format**: JSON with standard structure `{ \"meta\": { \"rc\": \"ok\" }, \"data\": [...] }`\n- **MAC Addresses**: Use lowercase, typically without separators (e.g., `00112233aabb`)\n\n## ⚡ Quick Start\n\n```javascript\nconst response = await axios.post(\n  \"https://unifi.example.com/api/login\",\n  {\n    username: \"admin\",\n    password: \"password\",\n    remember: true,\n  },\n  {\n    withCredentials: true,\n    httpsAgent: new https.Agent({ rejectUnauthorized: false }),\n  }\n);\n```\n\n## 🔌 API Endpoint Reference\n\n### 🔐 Authentication\n\n| Operation      | Method | Endpoint      | Description                     |\n| -------------- | ------ | ------------- | ------------------------------- |\n| Login          | POST   | `/api/login`  | Establish authenticated session |\n| Verify Session | GET    | `/api/self`   | Check if session is valid       |\n| Logout         | POST   | `/api/logout` | End current session             |\n\n```json\n{\n  \"username\": \"admin\",\n  \"password\": \"your_password\",\n  \"remember\": true\n}\n```\n\n### 🛠️ Device Management\n\n| Operation        | Method | Endpoint                                | Description              |\n| ---------------- | ------ | --------------------------------------- | ------------------------ |\n| List All Devices | GET    | `/api/s/{site}/stat/device`             | Get all network devices  |\n| Device Details   | GET    | `/api/s/{site}/stat/device/{mac}`       | Get specific device info |\n| Device Stats     | GET    | `/api/s/{site}/stat/device/{mac}/stats` | Get performance metrics  |\n| Restart Device   | POST   | `/api/s/{site}/cmd/devmgr`              | Restart specific device  |\n| Upgrade Firmware | POST   | `/api/s/{site}/cmd/devmgr`              | Upgrade device firmware  |\n\n```json\n{\n  \"cmd\": \"restart\",\n  \"mac\": \"00:11:22:33:44:55\"\n}\n```\n\n### 👥 Client Management\n\n| Operation         | Method | Endpoint                        | Description                        |\n| ----------------- | ------ | ------------------------------- | ---------------------------------- |\n| Active Clients    | GET    | `/api/s/{site}/stat/sta`        | List all connected clients         |\n| All Clients       | GET    | `/api/s/{site}/stat/alluser`    | List all clients (inc. historical) |\n| Client Details    | GET    | `/api/s/{site}/stat/user/{mac}` | Get specific client details        |\n| Block Client      | POST   | `/api/s/{site}/cmd/stamgr`      | Block network access               |\n| Unblock Client    | POST   | `/api/s/{site}/cmd/stamgr`      | Restore network access             |\n| Disconnect Client | POST   | `/api/s/{site}/cmd/stamgr`      | Force client disconnection         |\n\n```json\n{\n  \"cmd\": \"block-sta\",\n  \"mac\": \"aa:bb:cc:dd:ee:ff\"\n}\n```\n\n### 🌐 Internet Access Control\n\n| Operation        | Method | Endpoint                              | Description                   |\n| ---------------- | ------ | ------------------------------------- | ----------------------------- |\n| Set Access       | POST   | `/api/s/{site}/rest/user/{client_id}` | Allow/deny internet access    |\n| Bandwidth Limits | POST   | `/api/s/{site}/rest/trafficrule`      | Create client bandwidth rules |\n\n```json\n{\n  \"use_fixedip\": true,\n  \"network_access\": \"deny\",\n  \"fixedip\": \"192.168.1.100\",\n  \"usergroup_id\": \"existing-group-id\"\n}\n```\n\n### 🗺️ Network Configuration\n\n| Operation      | Method | Endpoint                              | Description                 |\n| -------------- | ------ | ------------------------------------- | --------------------------- |\n| List Networks  | GET    | `/api/s/{site}/rest/networkconf`      | Get all networks            |\n| Create Network | POST   | `/api/s/{site}/rest/networkconf`      | Create new wireless network |\n| Update Network | PUT    | `/api/s/{site}/rest/networkconf/{id}` | Modify existing network     |\n| Delete Network | DELETE | `/api/s/{site}/rest/networkconf/{id}` | Remove network              |\n\n```json\n{\n  \"name\": \"Guest Network\",\n  \"x_passphrase\": \"guestpassword\",\n  \"security\": \"wpapsk\",\n  \"wpa_mode\": \"wpa2\",\n  \"enabled\": true,\n  \"is_guest\": true,\n  \"vlan_enabled\": false\n}\n```\n\n### 🏷️ Site Management\n\n| Operation   | Method | Endpoint                     | Description              |\n| ----------- | ------ | ---------------------------- | ------------------------ |\n| List Sites  | GET    | `/api/self/sites`            | Get all accessible sites |\n| Site Health | GET    | `/api/s/{site}/stat/health`  | Get site health metrics  |\n| Create Site | POST   | `/api/s/default/cmd/sitemgr` | Create new site          |\n| Delete Site | POST   | `/api/s/default/cmd/sitemgr` | Remove existing site     |\n\n```json\n{\n  \"cmd\": \"add-site\",\n  \"name\": \"New Office\",\n  \"desc\": \"Branch office location\"\n}\n```\n\n### 📊 Statistics \u0026 Monitoring\n\n| Operation        | Method | Endpoint                               | Description                      |\n| ---------------- | ------ | -------------------------------------- | -------------------------------- |\n| DPI Stats        | GET    | `/api/s/{site}/stat/dpi`               | Get Deep Packet Inspection stats |\n| Client DPI       | GET    | `/api/s/{site}/stat/stadpi`            | Get client-specific DPI stats    |\n| Historical Stats | GET    | `/api/s/{site}/stat/report/daily.site` | Get site history metrics         |\n| Gateway Stats    | GET    | `/api/s/{site}/stat/gateway`           | Get USG performance metrics      |\n\n### Pagination and Filtering\n\n| Parameter | Description                                       | Example                                        |\n| --------- | ------------------------------------------------- | ---------------------------------------------- |\n| `_limit`  | Maximum number of items to return                 | `/api/s/{site}/stat/sta?_limit=50`             |\n| `_start`  | Index to start from (for offset-based pagination) | `/api/s/{site}/stat/sta?_start=50`             |\n| `mac`     | Filter by MAC address                             | `/api/s/{site}/stat/sta?mac=001122334455`      |\n| `ip`      | Filter by IP address                              | `/api/s/{site}/stat/sta?ip=192.168.1.100`      |\n| `within`  | Timeframe for historical data in seconds          | `/api/s/{site}/stat/sta?within=86400`          |\n| `attrs`   | Comma-separated list of attributes to include     | `/api/s/{site}/stat/sta?attrs=mac,ip,hostname` |\n\n```javascript\nconst response = await api.get(\"/api/s/default/stat/sta\", {\n  params: {\n    _limit: 10,\n    _sort: \"-last_seen\",\n    attrs: \"mac,hostname,ip,signal,tx_bytes,rx_bytes\",\n  },\n});\n```\n\n## 🔔 WebSocket API\n\nUniFi Controller also provides a WebSocket interface for real-time event monitoring. This allows you to receive immediate notifications about network changes without polling.\n\n### 🔗 Connection Establishment\n\n```javascript\nconst WebSocket = require(\"ws\");\nconst axios = require(\"axios\");\nconst https = require(\"https\");\nconst cookieJar = {};\n\nconst api = axios.create({\n  baseURL: \"https://unifi.example.com\",\n  withCredentials: true,\n  httpsAgent: new https.Agent({ rejectUnauthorized: false }),\n});\n\nawait api\n  .post(\"/api/login\", {\n    username: \"admin\",\n    password: \"password\",\n  })\n  .then((response) =\u003e {\n    const cookies = response.headers[\"set-cookie\"];\n    if (cookies) {\n      cookies.forEach((cookie) =\u003e {\n        const [key, value] = cookie.split(\";\")[0].split(\"=\");\n        cookieJar[key] = value;\n      });\n    }\n  });\n\nconst cookieString = Object.entries(cookieJar)\n  .map(([key, value]) =\u003e `${key}=${value}`)\n  .join(\"; \");\n\nconst ws = new WebSocket(\"wss://unifi.example.com/wss/s/default/events\", {\n  headers: {\n    Cookie: cookieString,\n  },\n  rejectUnauthorized: false,\n});\n\nws.on(\"open\", () =\u003e {\n  console.log(\"WebSocket connection established\");\n});\n\nws.on(\"message\", (data) =\u003e {\n  const event = JSON.parse(data);\n  console.log(\"Received event:\", event);\n\n  if (event.data \u0026\u0026 event.data.meta \u0026\u0026 event.data.meta.message) {\n    const msgType = event.data.meta.message;\n    switch (msgType) {\n      case \"sta:sync\":\n        console.log(\"Client update:\", event.data.data);\n        break;\n      case \"device:sync\":\n        console.log(\"Device update:\", event.data.data);\n        break;\n    }\n  }\n});\n\nws.on(\"error\", (error) =\u003e {\n  console.error(\"WebSocket error:\", error);\n});\n\nws.on(\"close\", () =\u003e {\n  console.log(\"WebSocket connection closed\");\n});\n```\n\n### 🧾 Common Event Types\n\n| Event Type       | Description                | When Triggered                      |\n| ---------------- | -------------------------- | ----------------------------------- |\n| `sta:sync`       | Client status updates      | Client connects/disconnects/updates |\n| `device:sync`    | Device status updates      | Device status changes               |\n| `alarm`          | System alarms and warnings | New alert triggered                 |\n| `speedtest:done` | WAN speed test completed   | After running a speed test          |\n| `backup:done`    | Backup creation completed  | After creating a backup             |\n| `evt`            | Various system events      | Various actions on the system       |\n| `notification`   | System notifications       | New notification                    |\n\n### ✅ WebSocket Event Handling Best Practices\n\n1. **Automatic Reconnection**\n\n```javascript\nfunction connectWebSocket() {\n  const ws = new WebSocket(\"wss://unifi.example.com/wss/s/default/events\", {\n    headers: { Cookie: cookieString },\n    rejectUnauthorized: false,\n  });\n\n  const connectionTimeout = setTimeout(() =\u003e {\n    if (ws.readyState !== WebSocket.OPEN) {\n      ws.terminate();\n      console.log(\"Connection attempt timed out, retrying...\");\n      setTimeout(connectWebSocket, 5000);\n    }\n  }, 10000);\n\n  ws.on(\"open\", () =\u003e {\n    clearTimeout(connectionTimeout);\n    console.log(\"WebSocket connection established\");\n\n    const pingInterval = setInterval(() =\u003e {\n      if (ws.readyState === WebSocket.OPEN) {\n        ws.ping();\n      } else {\n        clearInterval(pingInterval);\n      }\n    }, 30000);\n  });\n\n  ws.on(\"close\", () =\u003e {\n    console.log(\"Connection closed, attempting to reconnect...\");\n    setTimeout(connectWebSocket, 5000);\n  });\n}\n\nconnectWebSocket();\n```\n\n2. **Event Filtering and Processing**\n\n```javascript\nconst eventHandlers = {\n  \"sta:sync\": (data) =\u003e {\n    const clientMac = data.mac;\n    const connectionState = data.state ? \"connected\" : \"disconnected\";\n    console.log(`Client ${clientMac} is now ${connectionState}`);\n  },\n  \"device:sync\": (data) =\u003e {\n    console.log(`Device ${data.name} (${data.mac}) updated: ${data.state}`);\n  },\n  alarm: (data) =\u003e {\n    console.log(`ALARM: ${data.msg} (Key: ${data.key}, Time: ${data.time})`);\n  },\n};\n\nws.on(\"message\", (rawData) =\u003e {\n  try {\n    const event = JSON.parse(rawData);\n\n    if (event.data \u0026\u0026 event.data.meta \u0026\u0026 event.data.meta.message) {\n      const msgType = event.data.meta.message;\n\n      if (eventHandlers[msgType]) {\n        eventHandlers[msgType](event.data.data);\n      } else {\n        console.log(`Unhandled event type: ${msgType}`);\n      }\n    }\n  } catch (error) {\n    console.error(\"Error processing WebSocket message:\", error);\n  }\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuchkunrakhimow%2Funifi-best-practices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuchkunrakhimow%2Funifi-best-practices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuchkunrakhimow%2Funifi-best-practices/lists"}