netbox_unifi is a fork of netbox-unifi-sync to make changes along with special feature use cases. netbox_unifi is a NetBox 4.2+ plugin that syncs your UniFi controller to NetBox to create a source of truth.
All credits go to the team at unifi2netbox. Without them, this repo wouldn't exist and cool stuff wouldn't happen 😉
flowchart LR
U["UniFi Controller(s)"] --> P["netbox_unifi plugin<br/>NetBox Jobs (RQ)"]
P --> N["NetBox DCIM/IPAM/Wireless"]
A["Plugin UI<br/>Settings/Controllers/Mappings"] --> P
flowchart TD
A[Scheduled Job / Manual Trigger] --> B[NetBox RQ Worker]
B --> C[Load Plugin Settings]
C --> D[Authenticate to UniFi]
D --> E[Fetch Data from UniFi API]
E --> F[Normalize / Map Data]
F --> G[Create / Update NetBox Objects]
G --> H[Write Audit Log]
flowchart LR
U[UniFi API] --> V[Devices]
U --> W[VLANs]
U --> X[WLANs]
U --> Y[DHCP Scopes]
V --> M1[Device Mapping]
W --> M2[VLAN Mapping]
X --> M3[Wireless Mapping]
Y --> M4[IP Range Mapping]
M1 --> NB[NetBox ORM]
M2 --> NB
M3 --> NB
M4 --> NB
NB --> DB[(NetBox Database)]
flowchart TD
A[UniFi Object] --> B{Exists in NetBox?}
B -- Yes --> C[Update Object]
B -- No --> D[Create Object]
C --> E[Mark as Synced]
D --> E
E --> F{Cleanup Enabled?}
F -- Yes --> G[Remove Stale Objects]
F -- No --> H[Keep Orphaned Objects]
flowchart LR
A[Plugin Settings] --> B{Auth Mode}
B -- API Key --> C[Attach Authorization Header]
B -- Username/Password --> D[Session Login]
D --> E[Optional MFA]
C --> F[Authenticated API Session]
E --> F
F --> G[Execute Requests]
flowchart TD
A[API Request] --> B{Success?}
B -- Yes --> C[Process Response]
B -- No --> D{Retry < Max Attempts?}
D -- Yes --> E[Backoff + Retry]
D -- No --> F[Log Error]
F --> G[Mark Job Failed]
- Device sync (devices, interfaces, VLANs, prefixes, WLANs, uplink relations, IP assignments)
- Security Appliance sync — VLAN subinterfaces and gateway IPs created correctly, including Integration API controllers
- MAC address sync — per-port MACs (Legacy API) or device base MAC on Port 1 (Integration API); NetBox 4.5
MACAddressmodel compatible - DHCP scope sync to NetBox IP Ranges
- Client IP sync to NetBox IPAM with
unifi-clienttagging, stable MAC markers, descriptions, and interface assignment by MAC when NetBox has a matching DCIM or virtualization interface - NetBox Change Log support for global settings, controllers, and site mappings
- UniFi auth via API key or legacy login (username/password + optional MFA)
- Manual and scheduled sync jobs
- Runtime settings stored in plugin models (
Settings,Controllers,Site mappings)
Note
Normal sync direction is UniFi -> NetBox. DHCP-to-static writeback is the only
UniFi write path, and it runs only when dhcp_writeback_enabled is explicitly enabled.
pip install netbox-unifiPyPI project page: https://pypi.org/project/netbox-unifi/
For netbox-docker, add the package to local_requirements.txt before build:
echo "netbox-unifi" >> local_requirements.txtImportant
The plugin must be installed in the same environment as both NetBox and the worker container. Otherwise scheduled jobs will fail.
PLUGINS = ["netbox_unifi"]
PLUGINS_CONFIG = {
"netbox_unifi": {}
}python manage.py migrateCaution
Skipping migrations will result in database errors and plugin initialization failure.
Go to:
Plugins -> UniFi Sync
Configure:
- Settings (
tenant_name,netbox_roles, defaults) - Controllers (URL, auth mode, credentials)
- Site mappings (if UniFi/NetBox site names differ)
Tip
Use a dedicated read-only API account in UniFi for synchronization. This limits impact if credentials are exposed.
UI: Plugins -> UniFi Sync -> Sync Dashboard -> Run now
CLI:
python manage.py netbox_unifi_run --dry-run --json
python manage.py netbox_unifi_run
python manage.py netbox_unifi_run --cleanupImportant
Always run the first execution with --dry-run to verify intended changes before writing to NetBox.
Caution
The --cleanup flag removes objects in NetBox that no longer exist in UniFi. Review carefully before using in production.
Set credentials only in:
Plugins -> UniFi Sync -> Controllers
Warning
Never store UniFi credentials in PLUGINS_CONFIG. Configuration files may end up in version control or logs.
The plugin supports NetBox Scheduled Jobs.
Recommended intervals:
- Small environments: every 30–60 minutes
- Larger environments: every 2–4 hours
Note
High sync frequency increases load on both the UniFi controller and NetBox worker processes.
For normal NetBox users, grant permissions through NetBox object permissions:
- View dashboard/run history:
viewonnetbox_unifi.SyncRun - Queue a manual sync job:
addonnetbox_unifi.SyncRun - Manage controllers:
view/add/change/deleteonnetbox_unifi.UnifiController - Test controller connectivity:
changeonnetbox_unifi.UnifiController - Manage site mappings:
view/add/change/deleteonnetbox_unifi.SiteMapping - Manage global settings:
view/changeonnetbox_unifi.GlobalSyncSettings - View audit log:
viewonnetbox_unifi.PluginAuditEvent
The legacy custom permission netbox_unifi.run_sync is still accepted by
the view for compatibility, but NetBox object permissions map naturally to
netbox_unifi.add_syncrun.
The legacy custom permission netbox_unifi.test_controller is also
accepted, but NetBox object permissions map naturally to
netbox_unifi.change_unificontroller.
- SSL verification defaults to true
- Secrets are redacted in run history and audit logs
- Timeouts, retries, and backoff are configurable
Important
If disabling SSL verification for testing, restrict access to the controller network. Never disable SSL verification in production environments.
- Server install guide
- NetBox plugin mode
- Configuration reference
- Troubleshooting
- Release and PyPI publish
- netbox-docker setup
- Wiki source pages
- GitHub Wiki
- Bump version in:
- pyproject.toml (
[project].version) - netbox_unifi/version.py (
__version__) - netbox-plugin.yaml (
compatibility[].release)
- pyproject.toml (
- Configure PyPI Trusted Publisher (OIDC) for this repository/workflow.
- Create tag
vX.Y.Zeither:- via GitHub Actions
Create Release Tag (manual)(recommended), or - manually with git:
git tag -a vX.Y.Z -m "Release vX.Y.Z"git push origin vX.Y.Z
- via GitHub Actions
release.ymlruns on the tag push, gates on lint/tests, and creates the GitHub Release.publish-python-package.ymlruns onrelease: publishedand publishes to PyPI (can also be run manually for retry).
Note
GitHub releases created by release.yml use GITHUB_TOKEN. If GitHub does not
emit a follow-up release: published workflow event, run Publish Python Package
manually from Actions with the same tag.
Caution
Version mismatch between pyproject.toml, version.py, and netbox-plugin.yaml will break the release pipeline.