Why Automate with the NetBox API?
NetBox's web interface is excellent for manual operations — adding a device, updating a rack, checking IP allocations. But for DC teams managing hundreds or thousands of assets, manual operations do not scale. The NetBox REST API is what transforms NetBox from a DCIM platform into an automation platform.
With the API, you can:
Import thousands of devices in minutes, with per-record error handling
Query rack utilisation across all sites and generate capacity reports
Detect changes between two inventory snapshots
Synchronise NetBox with external systems (CMDB, monitoring, ITSM)
Automate IP address allocation and interface assignment
Build custom dashboards and reports from live NetBox data
This guide covers the key endpoints, authentication patterns, and Python examples for the most common DC automation tasks.
Authentication
NetBox uses token-based authentication. Every API request must include an Authorization header:
```
Authorization: Token your-api-token-here
```
Create a dedicated token for each integration (Profile → API Tokens → Add Token). Assign the minimum required permissions — a read-only token for reporting scripts, a write token for import scripts. Never use a personal token in automation.
The pynetbox SDK
For Python automation, pynetbox is the recommended approach. Install it with:
```bash
pip install pynetbox
```
Connect to your NetBox instance:
```python
import pynetbox
import os
nb = pynetbox.api(
url="https://netbox.yourdomain.com",
token=os.environ["NETBOXAPITOKEN"]
)
```
Bulk Device Import
Importing devices via the API is faster and more reliable than CSV import for large datasets. The API provides per-record error handling — a failed record does not abort the entire batch.
```python
import pynetbox
import csv
import os
nb = pynetbox.api(
url="https://netbox.yourdomain.com",
token=os.environ["NETBOXAPITOKEN"]
)
devicestocreate = []
with open("struktivenetboxexport.csv") as f:
reader = csv.DictReader(f)
for row in reader:
devicestocreate.append({
"name": row["name"],
"devicerole": {"slug": row["devicerole"]},
"devicetype": {"slug": row["devicetype"]},
"site": {"slug": row["site"]},
"status": row["status"],
"serial": row["serial"] or None,
})
BATCH_SIZE = 100
created = 0
errors = []
for i in range(0, len(devicestocreate), BATCH_SIZE):
batch = devicestocreate[i:i + BATCH_SIZE]
try:
result = nb.dcim.devices.create(batch)
created += len(result)
print(f"Batch {i//BATCH_SIZE + 1}: created {len(result)} devices")
except pynetbox.RequestError as e:
errors.append({"batch": i//BATCH_SIZE + 1, "error": str(e)})
print(f"Batch {i//BATCH_SIZE + 1}: error — {e}")
print(f"\nTotal created: {created}")
```
Rack Utilisation Query
Query rack utilisation across all sites:
```python
import pynetbox
import os
nb = pynetbox.api(
url="https://netbox.yourdomain.com",
token=os.environ["NETBOXAPITOKEN"]
)
racks = nb.dcim.racks.all()
for rack in racks:
devices = nb.dcim.devices.filter(rack_id=rack.id)
occupiedu = sum(d.uheight for d in devices if d.u_height)
utilisationpct = (occupiedu / rack.uheight * 100) if rack.uheight else 0
print(f"{rack.site} / {rack.name}: {occupiedu}U / {rack.uheight}U ({utilisation_pct:.0f}%)")
```
Change Detection
Detect devices added or removed since a baseline snapshot:
```python
import pynetbox
import json
import os
from datetime import datetime
nb = pynetbox.api(
url="https://netbox.yourdomain.com",
token=os.environ["NETBOXAPITOKEN"]
)
with open("baseline.json") as f:
baseline = {d["name"]: d for d in json.load(f)}
current = {d.name: dict(d) for d in nb.dcim.devices.all()}
added = set(current.keys()) - set(baseline.keys())
removed = set(baseline.keys()) - set(current.keys())
print(f"Added: {len(added)} devices")
for name in sorted(added):
print(f" + {name}")
print(f"Removed: {len(removed)} devices")
for name in sorted(removed):
print(f" - {name}")
```
Key API Endpoints Reference
| Object | Endpoint | Common Operations |
|---|---|---|
| Devices | /api/dcim/devices/ | CRUD, filter by site/rack/status |
| Racks | /api/dcim/racks/ | CRUD, get rack utilisation |
| Sites | /api/dcim/sites/ | CRUD, filter by region |
| Manufacturers | /api/dcim/manufacturers/ | CRUD, slug lookup |
| Device Types | /api/dcim/device-types/ | CRUD, filter by manufacturer |
| Interfaces | /api/dcim/interfaces/ | CRUD, filter by device |
| IP Addresses | /api/ipam/ip-addresses/ | CRUD, filter by prefix |
Combining Struktive with the NetBox API
The most efficient pipeline for large-scale asset imports combines Struktive's normalisation output with the NetBox API:
Export your raw asset inventory from your source system
Upload to Struktive — the normalisation pipeline standardises vendor names, expands model abbreviations, parses location strings, and generates a NetBox-compatible CSV
Use the Python import script above to load the Struktive output via the API
Verify the import using the rack utilisation and change detection scripts
For the full NetBox import guide, see How to Import Data into NetBox. For the NetBox slug generation rules, see NetBox Slug Generation Deep Dive.