nb-cli is a NetBox CLI built on pynetbox for three audiences:
- Operators who need a dependable terminal workflow
- Automation that needs stable output and predictable exit codes
- LLM/agent wrappers that need an explicit execution contract instead of free-form API access
- Generic CRUD commands covering every NetBox REST endpoint
- ~46 typed workflow commands with friendly flags and automatic field resolution
- IP and prefix allocation helpers
- Bulk update and bulk delete operations
- Schema and resource discovery from live OpenAPI
- JSON, JSONL, text, and table output modes
- Multi-profile configuration (CLI flags > env vars >
.nb-cli.toml>~/.config/nb-cli/config.toml) - Verbose built-in help including long-form topic guides (
nb-cli help <topic>) - Validated against NetBox 4.5.3
pip install nb-cli-toolOr with uv:
uv pip install nb-cli-toolThe console entry points are nb-cli and nbx.
# Discover the instance
nb-cli status
nb-cli resources --search device
nb-cli schema dcim.devices
nb-cli choices dcim.devices
# Read data
nb-cli query dcim.devices --filter site=nyc1 --format table
nb-cli device list --filter status=active --format table
nb-cli device show --lookup name=edge01
# Write data safely (--dry-run to preview, --yes to confirm)
nb-cli device create --name edge01 --device-type qfx5120 --role leaf --site nyc1 --yes
nb-cli device update --lookup name=edge01 --status active --serial ABC123 --yes --diff
nb-cli prefix allocate-ip --lookup prefix=10.0.10.0/24 --count 2 --status active --yes
nb-cli ip-address assign-interface --lookup address=10.0.10.10/24 --device edge01 --interface xe-0/0/0 --yes
# Raw escape hatch for unsupported endpoints
nb-cli request get /api/dcim/devices/?name=edge01Work with any NetBox resource path — no typed wrapper required.
version— print installed versionhelp [topic]— long-form help topicsstatus— fetch NetBox status endpointopenapi— fetch raw OpenAPI documentresources— list resources discovered from OpenAPIschema <resource>— show fields and parameters for a resourcechoices <resource>— return valid choices for type/status/protocol fieldsquery <resource>— list objects with filtering, pagination, field selectionget <resource>— fetch a single object by ID or lookupcreate <resource>— create one object or a bulk list from JSONupdate <resource>— patch an object with JSON payloaddelete <resource>— delete an object by ID or lookupbulk-update <resource>— PATCH multiple objects in one request (each must includeid)bulk-delete <resource>— DELETE multiple objects by ID in one requestrequest <method> <path>— execute any raw REST request
Resource-specific commands with friendly flags and automatic slug/name-to-ID resolution. All support list, show, create, update, and delete.
Circuits
provider— circuit providers (Zayo, Lumen, etc.)provider-account— provider billing accountscircuit-type— circuit type definitionscircuit— individual circuits
DCIM — Core
manufacturerdevice-roleplatformdevice-typesitelocationrackdeviceinterfacecable
DCIM — Device Components
console-portconsole-server-portpower-portpower-outletrear-portfront-port(requires existingrear-port)module-bayinventory-item
DCIM — Power Infrastructure
power-panelpower-feed
Tenancy
tenant-grouptenantcontact-groupcontacttag
IPAM — Core
vlanvrfprefixip-address
IPAM — Extended
rir— Regional Internet Registriesasn— Autonomous System Numbersip-rangeroute-targetfhrp-group— VRRP/HSRP/GLBP/CARP groupsservice— IP services on devices or VMs
Virtualization
cluster-typecluster-groupclustervirtual-machinevm-interface
Extras
custom-fieldwebhookevent-rulesaved-filter
# Allocate IPs from a prefix
nb-cli prefix allocate-ip --lookup prefix=10.0.10.0/24 --count 5 --status active --yes
# Allocate child prefixes
nb-cli prefix allocate-prefix --lookup prefix=10.0.0.0/16 --prefix-length 24 --count 4 --yes
# Assign an IP to a device interface or VM interface
nb-cli ip-address assign-interface --lookup address=10.0.10.10/24 --device edge01 --interface xe-0/0/0 --yes
nb-cli ip-address assign-interface --lookup address=192.0.2.1/32 --vm app01 --vm-interface eth0 --yesnb-cli query dcim.devices --format json # default: structured envelope
nb-cli query dcim.devices --format jsonl # one object per line (stream-friendly)
nb-cli query dcim.devices --format table # human-readable columns
nb-cli query dcim.devices --format text # pretty-printed textConfiguration is loaded in priority order:
- CLI flags
- Environment variables (
NBCLI_URL,NBCLI_TOKEN, etc.) .nb-cli.tomlin the current directory~/.config/nb-cli/config.toml
Example config with multiple profiles:
default_profile = "lab"
[profiles.lab]
url = "https://netbox-lab.example.com"
token_env = "NETBOX_TOKEN_LAB"
verify_ssl = true
timeout = 30
[profiles.prod]
url = "https://netbox.example.com"
token_env = "NETBOX_TOKEN_PROD"
verify_ssl = true
threading = true
strict_filters = trueSwitch profiles:
nb-cli --profile prod device list --filter status=activenb-cli --help
nb-cli device create --help
nb-cli help overview
nb-cli help generic
nb-cli help device
nb-cli help prefix
nb-cli help ip-address
nb-cli help circuits
nb-cli help tenancy
nb-cli help virtualization
nb-cli help ipam-extras
nb-cli help dcim-components
nb-cli help extras
nb-cli help bulk
nb-cli help configuration
nb-cli help output- JSON output is the default — wrappers depend on deterministic, parseable output.
- List queries default to
--limit 50. - Strict filter validation is enabled by default.
- All mutating commands require
--yesunless--dry-runis used. --dry-runpreviews the payload without sending it.--diffshows a before/after diff on updates.
Requirements: Python 3.11+, uv
git clone https://github.com/lmarte17/nb-cli
cd nb-cli
uv sync --devRun tests:
.venv/bin/python -m pytest tests/test_cli.py tests/test_config.py tests/test_client.py -vRun live integration tests against a real NetBox instance:
NBCLI_URL="https://netbox.example.com" \
NBCLI_TOKEN="..." \
.venv/bin/python -m pytest tests/test_live_integration.py -vMIT — see LICENSE.