Skip to main content
Cloud

Replica Cache API

Replica Cache is a read-only REST API that serves NetBox data from an operationally independent cache, delivering sub-50ms P95 query latency and resilience independent of the primary NetBox database. It is available as a premium-tier feature on NetBox Cloud.

Customer Preview: Replica Cache is in customer preview. The API surface may evolve in future releases.

For the interactive API reference (OpenAPI/ReDoc), visit /docs on your Replica Cache endpoint.


Why Use Replica Cache

  • Operational resilience - Replica Cache serves reads from an operationally independent cache. Your monitoring, reporting, and automation scripts keep working even during NetBox maintenance windows or outages.
  • Fast reads at scale - Queries return in single-digit milliseconds for most workloads. Aggregation and filtering happen server-side, reducing data transfer and client-side processing.
  • Zero load on the primary database - Every Replica Cache read is served from the cache. High-frequency polling, dashboards, and bulk data exports never touch the primary NetBox database.

Replica Cache complements the primary NetBox API - use it for read-heavy automation that benefits from speed and resilience, and continue using the primary API for writes and real-time consistency.

Replica Cache vs. TurboBulk: Both are premium-tier performance features. TurboBulk provides fast bulk reads and writes with exact consistency, operating directly against the primary database. Replica Cache offloads reads to an independent cache - eventually consistent, but zero primary database load and resilient to outages. They're complementary: TurboBulk for bulk writes and consistent reads, Replica Cache for high-frequency read automation and resilience.


Key Differences from the NetBox API

AspectNetBox APIReplica Cache API
Base path/api//replica-cache/v1/
Write supportFull CRUDRead-only (GET)
Response formatNested objects (e.g. nested site on device)Flat rows (foreign keys are IDs)
PaginationOffset-based (limit/offset)Cursor-based (limit/cursor)
Filter syntax?name=foo?filter[name]=foo
BranchingSupports branchesMain branch only
ConsistencyReal-timeNear-real-time - changes stream in within seconds (typically 1-2s)
AuthenticationAuthorization: Bearer <key>Authorization: Bearer <key> + NBC-Netbox-ID header

Replica Cache is not a drop-in replacement for the NetBox API. Responses use flat column values rather than nested objects, filter syntax differs, and write operations are not supported.


Authentication

Every request to /v1/* endpoints requires two headers:

HeaderValueDescription
AuthorizationBearer <token>Replica Cache API token issued by NetBox Labs for your tenant
NBC-Netbox-ID<tenant-id>Your NetBox Cloud tenant ID, found in the Cloud console. Must match the tenant the API token was issued for - mismatches are rejected with 403
BASE_URL="https://<your-netbox>.cloud.netboxapp.com/replica-cache"

curl -s \
-H "Authorization: Bearer $REPLICA_CACHE_API_TOKEN" \
-H "NBC-Netbox-ID: $TENANT_ID" \
"$BASE_URL/v1/_meta/tables"

Replica Cache uses tenant-bound API tokens that are separate from your NetBox Cloud API token - contact NetBox Labs Support to have one issued for your tenant. The token is permanently bound to a single tenant_id, so the value you send in NBC-Netbox-ID must match the tenant the token was issued for. If they disagree the server returns 403; if NBC-Netbox-ID is missing the server returns 400; if the token is unknown the server returns 401.


Quick Start

1. Discover available entities

Entity coverage varies by NetBox version and configuration. Start by listing the tables available in your cache:

curl -s \
-H "Authorization: Bearer $REPLICA_CACHE_API_TOKEN" \
-H "NBC-Netbox-ID: $TENANT_ID" \
"$BASE_URL/v1/_meta/tables"
{
"tables": [
{ "name": "dcim_device", "row_count": 1042 },
{ "name": "dcim_site", "row_count": 35 },
{ "name": "ipam_ipaddress", "row_count": 8491 }
]
}

2. List records

Query any entity using its {app}/{model} path (derived from the table name - dcim_device becomes dcim/devices):

curl -s \
-H "Authorization: Bearer $REPLICA_CACHE_API_TOKEN" \
-H "NBC-Netbox-ID: $TENANT_ID" \
"$BASE_URL/v1/dcim/devices?limit=2"
{
"count": 1042,
"next_cursor": "WzEsMl0",
"results": [
{ "id": 1, "name": "spine-01", "status": "active", "site_id": 5 },
{ "id": 2, "name": "spine-02", "status": "active", "site_id": 5 }
]
}

3. Get a single record

Fetch one record by its primary key:

curl -s \
-H "Authorization: Bearer $REPLICA_CACHE_API_TOKEN" \
-H "NBC-Netbox-ID: $TENANT_ID" \
"$BASE_URL/v1/dcim/devices/1"
{ "id": 1, "name": "spine-01", "status": "active", "site_id": 5 }

Querying

Filtering

Filter results using query parameters in the form filter[column]__operator=value. When no operator is specified, eq (exact match) is used.

# Devices with status "active" at site 5
curl -s \
-H "Authorization: Bearer $REPLICA_CACHE_API_TOKEN" \
-H "NBC-Netbox-ID: $TENANT_ID" \
"$BASE_URL/v1/dcim/devices?filter[status]=active&filter[site_id]=5"

Operators:

OperatorSyntaxDescriptionExample
eqfilter[col]=val or filter[col]__eq=valExact match (default)filter[status]=active
infilter[col]__in=a,b,cMatch any value in comma-separated listfilter[status]__in=active,staged
ilikefilter[col]__ilike=valCase-insensitive substring matchfilter[name]__ilike=spine
isnullfilter[col]__isnull=trueCheck for NULL (true) or NOT NULL (false)filter[serial]__isnull=false
gtfilter[col]__gt=valGreater thanfilter[id]__gt=100
ltfilter[col]__lt=valLess thanfilter[id]__lt=500

Column names correspond to database columns. Use the schema endpoint to discover available columns for each entity.

Sorting

Sort results with the sort parameter. Prefix with - for descending order:

?sort=name          # ascending by name
?sort=-id # descending by id

Default sort order is ascending by primary key.

Field Selection

Return only specific columns with the fields parameter:

?fields=id,name,status

The primary key column is always included in the response, even if not listed.


Pagination

Replica Cache uses cursor-based pagination. Each list response includes:

FieldDescription
countTotal number of rows matching your filters
next_cursorOpaque cursor string for the next page; null on the last page
resultsArray of records for the current page

Use the limit parameter to control page size (default: 50, maximum: 1000).

To paginate through all results, pass the next_cursor value from each response as the cursor parameter on the next request:

cursor=""
while true; do
response=$(curl -s \
-H "Authorization: Bearer $REPLICA_CACHE_API_TOKEN" \
-H "NBC-Netbox-ID: $TENANT_ID" \
"$BASE_URL/v1/dcim/devices?limit=100${cursor:+&cursor=$cursor}")

# Process results...
echo "$response" | jq '.results[]'

# Get next cursor; exit loop if null (last page)
cursor=$(echo "$response" | jq -r '.next_cursor // empty')
[ -z "$cursor" ] && break
done

Aggregation

Compute aggregate metrics without fetching individual records:

GET /v1/{app}/{model}/_aggregate

Parameters:

ParameterDescription
metriccount (default), sum, avg, min, or max
metric_fieldColumn to aggregate (required for all metrics except count)
group_byComma-separated columns to group by (maximum 3)

Example - count devices by status:

curl -s \
-H "Authorization: Bearer $REPLICA_CACHE_API_TOKEN" \
-H "NBC-Netbox-ID: $TENANT_ID" \
"$BASE_URL/v1/dcim/devices/_aggregate?metric=count&group_by=status"
{
"results": [
{ "status": "active", "value": 892 },
{ "status": "planned", "value": 120 },
{ "status": "offline", "value": 30 }
]
}

Example - average prefix length by VRF:

curl -s \
-H "Authorization: Bearer $REPLICA_CACHE_API_TOKEN" \
-H "NBC-Netbox-ID: $TENANT_ID" \
"$BASE_URL/v1/ipam/prefixes/_aggregate?metric=avg&metric_field=prefix_length&group_by=vrf_id"

Search across cached entities with a substring match:

GET /v1/_search?q=<term>
  • q - search term (minimum 2 characters)
  • limit - maximum results to return (default: 50, maximum: 200)

Results are drawn from NetBox's cached value index, matching across object representations.


Data Freshness

Replica Cache is fed by a continuous stream of changes from the primary NetBox database. Every create, update, and delete is propagated to the cache as it happens - not on a fixed polling interval - so a change made in NetBox typically appears in the cache within 1-2 seconds, and nearly always within 10 seconds.

Use the freshness endpoint to confirm how current each table is:

curl -s \
-H "Authorization: Bearer $REPLICA_CACHE_API_TOKEN" \
-H "NBC-Netbox-ID: $TENANT_ID" \
"$BASE_URL/v1/_meta/freshness"
{
"tables": {
"dcim_device": {
"last_flush": "2025-01-15T12:34:56Z",
"lag_ms": 1200
},
"dcim_site": {
"last_flush": "2025-01-15T12:34:55Z",
"lag_ms": 1800
}
}
}
FieldDescription
last_flushUTC timestamp of the most recent change applied to this table in the cache
lag_msMilliseconds elapsed since last_flush (wall-clock lag at query time)

Under normal operation, lag_ms is in the low single-digit seconds. Use this endpoint to verify freshness in automation pipelines or monitoring.


Schema Discovery

Replica Cache schema depends on your NetBox version and installed plugins. Use the metadata endpoints to discover available tables and columns at runtime.

List tables and row counts:

curl -s \
-H "Authorization: Bearer $REPLICA_CACHE_API_TOKEN" \
-H "NBC-Netbox-ID: $TENANT_ID" \
"$BASE_URL/v1/_meta/tables"
{
"tables": [
{ "name": "dcim_device", "row_count": 1042 },
{ "name": "dcim_site", "row_count": 35 }
]
}

Get column schema for a table:

curl -s \
-H "Authorization: Bearer $REPLICA_CACHE_API_TOKEN" \
-H "NBC-Netbox-ID: $TENANT_ID" \
"$BASE_URL/v1/_meta/tables/dcim_device/schema"
{
"table": "dcim_device",
"columns": [
{ "name": "id", "type": "BIGINT", "nullable": "NO" },
{ "name": "name", "type": "VARCHAR", "nullable": "YES" },
{ "name": "status", "type": "VARCHAR", "nullable": "NO" },
{ "name": "site_id", "type": "BIGINT", "nullable": "YES" }
]
}

Build filters and field selections against the columns returned here rather than hardcoding column names.


Error Handling

Errors are returned as JSON with an error field:

{ "error": "missing tenant header" }

Status codes:

CodeMeaning
200Success
400Bad request - invalid filter, cursor, sort column, or missing parameter
401Unauthorized - missing or invalid API token
404Not found - unknown endpoint, table, or record
405Method not allowed - only GET requests are supported
500Internal server error - query execution failed

Limitations

  • Read-only - no create, update, or delete operations. Use the primary NetBox API for writes.
  • Near-real-time, eventually consistent - changes stream from NetBox continuously and typically appear within 1-2 seconds (nearly always within 10s), but Replica Cache is not transactionally consistent with the primary. Do not rely on it for read-after-write consistency.
  • Main branch only - Replica Cache serves data from the main NetBox branch. Branching plugin branches are not available.
  • Flat responses - related objects are represented by foreign key IDs, not nested objects. Join data client-side if needed.
  • Schema varies by NetBox version - available columns may change across NetBox upgrades. Use the schema endpoint to discover columns at runtime.
  • Non-core object types require configuration - core NetBox object types are available by default. Plugin models and non-core types can be enabled by contacting the NetBox Cloud support team.
  • Customer preview - the API surface may change in future releases.

API Reference

All endpoints below require the Authorization and NBC-Netbox-ID headers.

EndpointDescriptionKey Parameters
GET /v1/_meta/tablesList available tables and row counts-
GET /v1/_meta/tables/{table}/schemaGet column definitions for a table-
GET /v1/_meta/freshnessPer-table freshness (last change + lag)-
GET /v1/_searchCross-entity substring searchq, limit
GET /v1/\{app\}/{model}List recordsfilter[col]__op, sort, fields, limit, cursor
GET /v1/\{app\}/\{model\}/{id}Get a single record by primary key-
GET /v1/\{app\}/{model}/_aggregateAggregate metricsmetric, metric_field, group_by

For the full OpenAPI specification, visit /docs on your Replica Cache endpoint.