<!--startmeta
custom_edit_url: "https://github.com/netdata/netdata/edit/master/src/crates/netflow-plugin/integrations/netbox.md"
meta_yaml: "https://github.com/netdata/netdata/edit/master/src/crates/netflow-plugin/metadata.yaml"
sidebar_label: "NetBox"
learn_status: "Published"
learn_rel_path: "Network Performance Monitoring/Network Flows/Enrichment Methods"
keywords: ['netbox', 'ipam', 'dcim', 'source of truth', 'prefix list', 'network identity']
message: "DO NOT EDIT THIS FILE DIRECTLY, IT IS GENERATED BY THE FLOWS' metadata.yaml FILE"
endmeta-->

<!-- markdownlint-disable-file -->

# NetBox


<img src="https://netdata.cloud/img/network-wired.svg" width="150"/>


Plugin: netflow-plugin
Module: netbox

<img src="https://img.shields.io/badge/maintained%20by-Netdata-%2300ab44" />

## Overview

Annotate network flows with tenant, site, role, VRF, and description metadata
from NetBox. [NetBox](https://github.com/netbox-community/netbox) is the most
widely deployed open-source IPAM / DCIM. It is Apache-2.0 licensed and maintained
by the netbox-community organization (commercial variants -- NetBox Cloud and
NetBox Enterprise -- are offered by NetBox Labs on top of the same upstream code).
Operators already curate prefix metadata in NetBox and want flow records to
inherit those labels automatically rather than maintaining a parallel list in
`netflow.yaml`.

This integration polls NetBox's Prefixes REST API at a configurable interval,
transforms the response with jq, and labels matching flow prefixes with whatever
fields you map. NetBox is the authoritative source -- when the same prefix is
tagged in NetBox and in the static `networks:` block, the static block wins
(operator override is intentional, see the
[Network Identity](https://github.com/netdata/netdata/blob/master/docs/npm/network-flows/enrichment.md)
concept page).

Use cases: applying your organisation's data-centre rack labels, tenant names,
environment tags (prod / staging / dev), and VRF / site identifiers to flows so
dashboards and queries surface "this is the staging tier in fra1" instead of a
raw CIDR.


Periodic HTTPS GET to `/api/ipam/prefixes/` on your NetBox host. Authentication is
a NetBox API token in the `Authorization` header. NetBox supports two token
formats:

- **Legacy v1 tokens** (`Authorization: Token <token>`) -- accepted by all NetBox
  versions, simplest to wire up.
- **v2 tokens** (NetBox 4.5+, `Authorization: Bearer nbt_<12-char-key>.<40-char-token>`) --
  the prefix `nbt_`, the token key, a dot, and the token secret are all part of
  the header value.

The plugin transports either format -- the value is whatever NetBox issued for the
service account.

The plugin runs the configured `transform` (jaq -- a jq-equivalent) over the
parsed JSON body and produces per-prefix objects. NetBox's response is paginated;
the plugin does **not** follow `next` links. Pass `?limit=0` (NetBox default
`MAX_PAGE_SIZE` is 1000; setting `0` removes the cap when the server config
allows) or an explicit `?limit=N` greater than your prefix count, or expose a
server-side aggregator that returns the full list at one URL.


This integration is supported on all platforms.

This integration supports multiple instances configured side-by-side.


### Default Behavior

#### Auto-Detection

Disabled by default. Add an entry under `enrichment.network_sources` with your NetBox URL and API token.

#### Limits

Resource use scales with the number of NetBox prefixes returned by the URL and transform. Use NetBox filtering when you only need a subset of VRFs, sites, tenants, or roles.

#### Performance Impact

One HTTP request per refresh interval plus a jq transform over the response. Runtime enrichment does prefix matching for source and destination IPs, and cost scales with the number of loaded network-source records.

## Setup


### Prerequisites

#### NetBox API token with read scope on Prefixes

In NetBox, create or reuse a service-account user, then generate an API token
under "Admin > Users > Tokens". Restrict the token to read-only and (for
NetBox 4.x) limit the scope to `ipam.view_prefix`. The token value goes in the
`Authorization` header.

The plugin only reads -- never writes -- so a read-only token is sufficient
and recommended. Token format depends on the NetBox version:

- NetBox 3.x or earlier: `Token <40-char-hex>` (legacy).
- NetBox 4.0 through 4.4: legacy `Token <hex>`.
- NetBox 4.5+: legacy `Token <hex>` or new
  `Bearer nbt_<12-char-key>.<40-char-token>` (v2 tokens).


#### Bulk endpoint (`?limit=0` or aggregator)

The plugin fetches a single page. NetBox's default `PAGINATE_COUNT` is 50
and `MAX_PAGE_SIZE` is 1000. For inventories above 1000 prefixes, either
raise `MAX_PAGE_SIZE` server-side and pass `?limit=0`, or expose an internal
aggregator endpoint that walks pagination and returns the full list at one URL.


#### NetBox version-aware field mapping

NetBox **4.2** replaced the per-prefix `site` foreign key with a generic
`scope` field (a prefix can now be scoped to a region, site group, site, or
location -- not just a site). API responses on 4.2+ omit `site` and expose
`scope` (read-only) plus `scope_type` / `scope_id`. Adjust your jq accordingly
-- on 4.2+ use `(.scope.name // "")`, on 4.1 and earlier use
`(.site.name // "")`.



### Configuration

#### Options

Add a named entry under `enrichment.network_sources` pointing at your NetBox.
The network source configuration accepts `url`, `method`,
`headers`, `proxy`, `tls`, `timeout`, `interval`, and `transform`. Authentication
is configured via the generic `headers:` map -- there is no NetBox-specific
auth helper.


<details open><summary>Config options</summary>



| Option | Description | Default | Required |
|:-----|:------------|:--------|:---------:|
| url | NetBox prefixes API endpoint, including `?limit=` (recommend `?limit=0` for full inventory in one shot when the server's `MAX_PAGE_SIZE` allows it). |  | yes |
| headers.Authorization | NetBox API token. Use `Token <hex>` for legacy v1 or `Bearer nbt_<12-char-key>.<40-char-token>` for v4.5+ v2 tokens. |  | yes |
| interval | How often to refresh. NetBox is your source of truth; 5 minutes is typical for IPAMs that change frequently, 1 hour is fine for static inventories. | 60s | no |
| timeout | HTTP request timeout. Bump to 30-60s if your NetBox returns thousands of prefixes in one shot. | 10s | no |
| transform | jq expression mapping NetBox's `.results[]` to per-prefix objects with `prefix` and any of `name`, `role`, `site`, `region`, `country`, `state`, `city`, `tenant`, `asn`, `asn_name`. | . | yes |
| tls.ca_file | Path to your internal CA bundle when NetBox runs behind internal PKI. Disabling verification is rejected by the validator -- use this instead. |  | no |


</details>



#### via File

The configuration file name for this integration is `netflow.yaml`.


You can edit the configuration file using the [`edit-config`](https://github.com/netdata/netdata/blob/master/docs/netdata-agent/configuration/README.md#edit-configuration-files) script from the
Netdata [config directory](https://github.com/netdata/netdata/blob/master/docs/netdata-agent/configuration/README.md#locate-your-config-directory).

```bash
cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata
sudo ./edit-config netflow.yaml
```

##### Examples

###### NetBox 4.5+ with v2 token, scope-aware mapping

Standard NetBox 4.2+ wiring. Maps tenant, role, the new `scope` field
(covers site / region / site-group / location), and the human-readable
description. `?limit=0` returns all prefixes in one call when
`MAX_PAGE_SIZE` is set to `0` or `None` on the NetBox server.


```yaml
enrichment:
  network_sources:
    netbox:
      url: "https://netbox.example.internal/api/ipam/prefixes/?limit=0"
      headers:
        Authorization: "Bearer nbt_<12-char-key>.<40-char-token>"
      interval: 5m
      timeout: 30s
      transform: |
        .results[] | {
          prefix: .prefix,
          tenant: (.tenant.name // ""),
          role:   (.role.name // ""),
          site:   (.scope.name // ""),
          name:   (.description // "")
        }

```
###### NetBox 3.x / 4.0 / 4.1 with legacy site field

Pre-4.2 NetBox still exposes `site` directly on the Prefix object. Use a
legacy `Token` header and read `.site.name` instead of `.scope.name`.


<details open><summary>Config</summary>

```yaml
enrichment:
  network_sources:
    netbox:
      url: "https://netbox.example.internal/api/ipam/prefixes/?limit=10000"
      headers:
        Authorization: "Token abcdef0123456789abcdef0123456789abcdef01"
      interval: 15m
      transform: |
        .results[] | {
          prefix: .prefix,
          tenant: (.tenant.name // ""),
          role:   (.role.name // ""),
          site:   (.site.name // ""),
          name:   (.description // "")
        }

```
</details>

###### NetBox behind internal PKI (mTLS)

When NetBox is fronted by internal PKI. `tls.verify: false` is rejected at
config-load -- supply your CA explicitly and (optionally) a client
certificate.


<details open><summary>Config</summary>

```yaml
enrichment:
  network_sources:
    netbox:
      url: "https://netbox.example.internal/api/ipam/prefixes/?limit=0"
      headers:
        Authorization: "Token abcdef0123456789abcdef0123456789abcdef01"
      interval: 5m
      tls:
        enable: true
        ca_file: /etc/netdata/ssl/internal-ca.pem
        cert_file: /etc/netdata/ssl/netdata.crt
        key_file: /etc/netdata/ssl/netdata.key
      transform: |
        .results[] | {
          prefix: .prefix,
          tenant: (.tenant.name // ""),
          role:   (.role.name // ""),
          site:   (.scope.name // ""),
          name:   (.description // "")
        }

```
</details>

###### VRF-aware mapping (multi-tenant networks)

When the same RFC1918 prefix appears in multiple VRFs, fold the VRF name
into the friendly `name` so dashboards disambiguate. Note: the plugin keys
on `prefix` only -- if two rows share a CIDR, the last one wins. Filter the
NetBox query (`?vrf_id=N`) to scope the export.


<details open><summary>Config</summary>

```yaml
enrichment:
  network_sources:
    netbox-prod-vrf:
      url: "https://netbox.example.internal/api/ipam/prefixes/?limit=0&vrf_id=12"
      headers:
        Authorization: "Token abcdef0123456789abcdef0123456789abcdef01"
      interval: 5m
      transform: |
        .results[] | {
          prefix: .prefix,
          tenant: (.tenant.name // ""),
          role:   (.role.name // ""),
          site:   (.scope.name // ""),
          name:   ((.vrf.name // "default") + ": " + (.description // ""))
        }

```
</details>



### Only first 50 prefixes loaded

NetBox's default `PAGINATE_COUNT` is 50 and the plugin does not follow `next`
links. Pass `?limit=0` (NetBox removes the cap when `MAX_PAGE_SIZE` is
`0` server-side) or `?limit=N` larger than your inventory. For inventories
above the server's `MAX_PAGE_SIZE` (default 1000), expose a server-side
aggregator endpoint.


### 401 / 403 from NetBox

Token missing, expired, or wrong format. Verify with one of:
`curl -H "Authorization: Token <legacy-token>" https://netbox/api/ipam/prefixes/`
or
`curl -H "Authorization: Bearer nbt_<12-char-key>.<40-char-token>" https://netbox/api/ipam/prefixes/`.
On NetBox 4.5+ check whether the token is v1 (`Token <hex>`) or v2
(`Bearer nbt_<12-char-key>.<40-char-token>`) and use the matching header.
A v2 token sent with the legacy `Token` prefix is rejected as an invalid v1
token. Watch the journal
for `network-sources` warnings -- HTTP errors are logged there as
refresh-failed warnings.


### site is empty after upgrade to NetBox 4.2

NetBox 4.2 removed `site` from the Prefix model and replaced it with `scope`
(a generic foreign key that can reference region / site group / site /
location). Update the jq from `(.site.name // "")` to `(.scope.name // "")`.
Alternatively, key on `(.scope.name // .site.name // "")` so the same config
works across the upgrade boundary.


### VRF collisions (same CIDR in multiple VRFs)

The plugin's network-attributes trie keys on `prefix` only -- there is no VRF
dimension on the flow side. If NetBox lists `10.0.0.0/24` in three VRFs, only
the last row wins. Filter the export with `?vrf_id=N` per data-plane and run
one named source per VRF, or fold the VRF name into the friendly `name` so
dashboards disambiguate.


### Empty result triggers backoff

An empty `results` array (legitimate state for a freshly-installed NetBox)
is treated as a fetch failure by the cross-cutting source loop and triggers
exponential backoff. Add at least one synthetic prefix (e.g. a `RFC1918`
container) so the response is never empty.
