Bulk‑Import Devices into NetBox via REST API and CSV: A Step‑by‑Step Guide
Bulk‑import devices into NetBox with the REST API and CSV. Follow this concise guide to prepare your CSV, convert it to JSON, send a bulk POST, validate the import, and roll back if needed.
25 Sept 2025, 01:00 UTC

Problem & Takeaway
Managing a growing inventory of network equipment often means adding hundreds or thousands of devices to NetBox. The web UI is fine for a few items, but bulk‑importing via the REST API is faster, repeatable, and auditable. The key takeaway: use a validated CSV, convert it to JSON, POST to /api/dcim/devices/, verify the result, and keep a rollback plan.
Prerequisites
- NetBox 3.x (API v3) running on
https://netbox.example.com. - API token with the
automationscope. Store it in~/.netbox_tokenor as an environment variableNETBOX_TOKEN. - Python 3.8+ with
pandasandrequestslibraries for CSV‑to‑JSON conversion. - CSV file containing at least the mandatory columns:
name,device_type,device_role,site. Optional columns:serial,asset_tag,primary_ip4,primary_ip6. - NetBox backup (optional but recommended) –
pg_dumpof the PostgreSQL database.
Preparing the CSV
NetBox expects the CSV to reference existing objects by name or UUID. A minimal example:
name,device_type,device_role,site,serial,asset_tag,primary_ip4
core-sw1,Switch-48,Core Switch,Data Center,ABC123,1001,10.0.0.1
edge-rtr1,Router-4,Edge Router,Branch,XYZ987,2002,10.0.1.1
Validate the file locally before conversion:
python -m venv venv
source venv/bin/activate
pip install pandas
python validate_csv.py --file devices.csv
The validate_csv.py script checks that referenced device_type, device_role, and site exist in NetBox by querying the API. It also ensures that mandatory fields are present and that IP addresses are valid.
Converting CSV to JSON
NetBox accepts a list of device objects in JSON. Use the following Python helper to produce the payload:
import pandas as pd
import json
import os
csv_file = os.getenv('CSV_FILE', 'devices.csv')
netbox_url = os.getenv('NETBOX_URL', 'https://netbox.example.com')
# Load CSV
df = pd.read_csv(csv_file)
# Resolve foreign keys
# For brevity, assume helper functions get_uuid(name, endpoint)
# e.g., get_uuid('Switch-48', 'dcim/device-types/')
def resolve_fk(value, endpoint):
r = requests.get(f"{netbox_url}{endpoint}?name={value}")
r.raise_for_status()
return r.json()['results'][0]['id']
payload = []
for _, row in df.iterrows():
device = {
'name': row['name'],
'device_type': resolve_fk(row['device_type'], '/api/dcim/device-types/'),
'device_role': resolve_fk(row['device_role'], '/api/dcim/device-roles/'),
'site': resolve_fk(row['site'], '/api/dcim/sites/'),
}
if pd.notna(row.get('serial')):
device['serial'] = row['serial']
if pd.notna(row.get('asset_tag')):
device['asset_tag'] = row['asset_tag']
if pd.notna(row.get('primary_ip4')):
device['primary_ip4'] = row['primary_ip4']
if pd.notna(row.get('primary_ip6')):
device['primary_ip6'] = row['primary_ip6']
payload.append(device)
print(json.dumps(payload, indent=2))
Run the script and redirect output to payload.json:
python csv_to_json.py > payload.json
Auth & API Setup
All API calls require an Authorization header with a token. Store the token in ~/.netbox_token for convenience:
echo 'Token: ' > ~/.netbox_token
chmod 600 ~/.netbox_token
In scripts, read it with:
token = open(os.path.expanduser('~/.netbox_token')).read().strip().split(': ')[1]
headers = {
'Authorization': f'Token {token}',
'Content-Type': 'application/json',
'Accept': 'application/json',
}
Bulk POST Request
NetBox supports a single POST with an array of device objects. Use curl for a quick test or embed the request in your automation tool.
curl -X POST \
-H "Authorization: Token $(cat ~/.netbox_token | cut -d' ' -f2)" \
-H "Content-Type: application/json" \
-d @payload.json \
https://netbox.example.com/api/dcim/devices/
For large imports (10k+ devices), NetBox may throttle requests. Break the payload into chunks of 500 or use the --max-time and --retry options to handle transient failures.
Validation Checks
- Count Verification: After the POST, check the total device count:
- Individual Existence: Confirm a sample device:
- IP Allocation: Ensure primary IPs are assigned:
- Log Review: Check
/var/log/netbox/netbox.logfor any warnings or errors during the import.
curl -H "Authorization: Token $(cat ~/.netbox_token | cut -d' ' -f2)" \
https://netbox.example.com/api/dcim/devices/?limit=0 | jq '.count'
curl -H "Authorization: Token $(cat ~/.netbox_token | cut -d' ' -f2)" \
https://netbox.example.com/api/dcim/devices/?name=core-sw1 | jq '.results[0] | {name,serial,primary_ip4} '
curl -H "Authorization: Token $(cat ~/.netbox_token | cut -d' ' -f2)" \
https://netbox.example.com/api/ipam/ip-addresses/?address=10.0.0.1 | jq '.results[0] | {id,device}
'
Rollback Options
NetBox offers a bulk delete endpoint. If the import fails or you need to undo it, capture the IDs of the created devices (e.g., from the POST response or a filtered GET) and delete them:
curl -X DELETE \
-H "Authorization: Token $(cat ~/.netbox_token | cut -d' ' -f2)" \
https://netbox.example.com/api/dcim/devices/?id__in=123,124,125
Alternatively, restore a recent backup if the data set is large or the environment is production.
Practical Tips
- Use environment variables for URLs and tokens to keep scripts portable.
- Always run a dry‑run by posting to a staging NetBox instance first.
- Keep the CSV versioned; the same file can be reused for future imports.
- Log the API responses to a file for audit purposes.
- When importing into production, schedule the operation during a maintenance window to reduce risk.
Summary
Bulk‑importing devices into NetBox via the REST API is a repeatable, auditable process that scales far beyond the UI. By validating the CSV, converting it to JSON, posting the payload, and performing post‑import checks, you can confidently populate your inventory. Always keep a rollback plan—either the bulk delete endpoint or a recent database backup—to recover from unexpected issues. With these steps, you can automate large-scale device onboarding and keep NetBox in sync with your network topology.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.