Networking Minerva User Guide

Read the Network Graph with the REST API

Export the NVIDIA Minerva topology model for inventory integration, topology visualization, and network automation. The API returns hierarchy, devices, physical connections, BGP adjacencies, and NVLink components in device-based pages. It is a read-only view of the current model.

Attribute

Value

Method

POST

Endpoint

/minerva/api/v2/export-topology

Request format

application/json

Response formats

application/json, application/x-ndjson

Default page size

100 devices

Maximum page size

500 devices

Authentication and Headers

Use the HTTPS endpoint provided by your deployment and supply its API key. When API authentication is enabled, a missing or invalid key returns HTTP 403 with an empty body.

Header

Value

Requirement

X-Api-Key

Deployment API key

Required when API authentication is enabled.

Content-Type

application/json

Required when sending a JSON body.

Accept

application/json or application/x-ndjson

Optional; defaults to JSON.

Keep API keys outside source code and logs. The examples use environment variables; configure certificate trust for your deployment rather than disabling TLS verification.

Request

An omitted body or {} requests the first page of all hierarchy devices, with both topology layers and summary detail. A supplied body must be a JSON object; JSON null is not an empty request.

Example: export Ethernet and BGP topology for one east-west device.

Bash
curl --fail-with-body --request POST \
  "$MINERVA_URL/minerva/api/v2/export-topology" \
  --header "X-Api-Key: $MINERVA_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Accept: application/json" \
  --data '{
    "layers": ["east-west"],
    "fabricType": "east-west",
    "scope": {"devices": ["leaf-1"]},
    "deviceLimit": 100
  }'

Set MINERVA_URL to the deployment origin, for example https://minerva.example.com, without the API path or a trailing slash.

Request Parameters

All parameters are optional. Enum values and modeled names are case-sensitive.

Parameter

Type

Default

Contract

layers

string array

["east-west","nvlink"]

Nonempty selection of east-west and/or nvlink, without duplicates.

fabricType

string

Omitted: all fabrics

east-west or north-south. Exact match against the device's modeled fabric type. Explicit null is invalid.

detail

string

summary

summary or full. Full detail adds modeled properties to group, device, and component records.

scope

object

{}

Additive selectors described below.

deviceLimit

integer

100

Devices processed per page, from 1 through 500. Booleans are invalid.

cursor

object or null

Omitted

Use the previous response's nextCursor unchanged. Omitted or null starts a new traversal.

The legacy include and pageSize parameters are rejected. Use layers and deviceLimit, respectively. Only the parameters documented here form the supported request contract.

Topology Layers

layers selects which topology data to return; it does not select fabric membership.

Layer

Data

east-west

Ethernet-facing hierarchy and devices, physical Layer-2 neighbors, and BGP sessions.

nvlink

Rack hierarchy and devices, NVLink neighbors, and hosted components such as GPUs.

Despite its name, the east-west layer includes Ethernet and BGP data for north-south devices as well. Interfaces are represented on neighbor ends, not as standalone interface records. This endpoint is not an exhaustive interface inventory.

Fabric Filtering

fabricType selects devices before pagination and intersects that selection with scope. Both values are supported:

JSON
{"fabricType":"east-west","layers":["east-west"]}
JSON
{"fabricType":"north-south","layers":["east-west"]}

Omitting fabricType includes devices of either fabric type and devices without a fabric tag. A supplied value matches the stored property exactly; the API does not infer membership from device role, name, or group ancestry.

Untagged shared hosts are not selected as complete devices by either filter. They can still appear as direct neighbor context. Likewise, a selected device can have a neighbor in another fabric. A neighbor reference does not add the far-end device to the page or its device count.

Scope

Parameter

Type

Selection

scope.datacenters

string array

Datacenter group names.

scope.pods

string array

Pod group names.

scope.sus

string array

Scalable-unit (SU) group names.

scope.racks

string array

Rack group names.

scope.devices

string array

Device names.

scope.jobId

nonempty string

Groups and devices associated with a job.

Arrays default to []; jobId defaults to omitted. Unknown scope fields are rejected. Values within and across selectors are combined by union, not intersection. A selected group contributes its descendant devices. An empty scope does not restrict the device selection.

For example, this request selects tagged north-south devices in Pod-NS, plus the explicitly named device if it has the same fabric tag:

JSON
{
  "fabricType": "north-south",
  "layers": ["east-west"],
  "scope": {
    "pods": ["Pod-NS"],
    "devices": ["border-leaf-1"]
  }
}

Each selected device retains its live hierarchy ancestry and direct connections. Sibling devices are not selected merely because they share an ancestor. Devices without a modeled hierarchy path are not page anchors, although they may be referenced by neighbor records.

Job associations are added to any explicit selectors. Datacenter context does not broaden a job that already identifies more specific groups or devices. If a resolved job contributes no selectors and no explicit selectors are supplied, the request is unscoped. Consumers requiring a strictly job-bounded export should verify that the job has topology associations.

JSON Response

Successful requests return HTTP 200. The response contains exactly one record collection, determined by layers.

Requested layers

Record collection

Both layers

topology.records

Only east-west

eastWest.records

Only nvlink

nvlink.records

Response Fields

Field

Type

Meaning

cursorScope.id

string

Fingerprint of the requested layers, detail, scope, and fabric filter. Not a snapshot identifier or resume token.

cursorScope.createdAt

timestamp string

UTC response-generation time, not the collection time of the topology data.

layers

string array

Selected layers in canonical order: east-west, then nvlink.

fabricType

string

Selected fabric filter; omitted when no filter was supplied.

detail

string

Selected detail level.

devicesReturned

integer

Number of hierarchy device anchors processed on this page, excluding boundary neighbors.

nextCursor

object or null

Resume position for the next page; null when traversal is complete.

complete

boolean

True when no further device page is available.

topology.records, eastWest.records, or nvlink.records

object array

Ordered topology records. Only the applicable collection is present.

A successful response does not include a success field. An empty selection returns zero devices, an empty record array, nextCursor: null, and complete: true.

devicesReturned is not a record count. With a single layer selected, a processed device may have no record in that layer's projection. Group context and neighbor references also make the record count different from the device count.

Example Response

The following represents a modeled device with one unresolved BGP session. The request is the single-device example above; metadata values are illustrative.

JSON
{
  "cursorScope": {
    "id": "request:4bdbca9016c484238d7c",
    "createdAt": "2026-10-05T18:00:00+00:00"
  },
  "layers": ["east-west"],
  "fabricType": "east-west",
  "detail": "summary",
  "devicesReturned": 1,
  "nextCursor": null,
  "complete": true,
  "eastWest": {
    "records": [
      {
        "type": "datacenter",
        "name": "DC1",
        "parent": null,
        "children": [{"type":"pod","name":"Pod-1"}]
      },
      {
        "type": "pod",
        "name": "Pod-1",
        "parent": "DC1",
        "children": [{"type":"device","name":"leaf-1","role":"leaf","fabricType":"east-west"}]
      },
      {
        "type": "device",
        "name": "leaf-1",
        "role": "leaf",
        "fabricType": "east-west",
        "parent": "Pod-1"
      },
      {
        "type": "neighbor",
        "neighborType": "bgp",
        "from": {
          "device": "leaf-1",
          "fabricType": "east-west",
          "vrf": "default",
          "peerId": "192.0.2.2",
          "localAddress": "192.0.2.1"
        },
        "to": {},
        "resolved": false,
        "peerType": "EBGP",
        "peerState": "Active"
      }
    ]
  }
}

Record Schemas

Records use topology names rather than internal graph identifiers. Optional modeled attributes are omitted when unavailable. Clients should tolerate additional fields and preserve records with incomplete metadata.

Hierarchy Groups

Field

Type

Meaning

type

string

datacenter, pod, su, or rack.

name

string

Modeled group name.

parent

string or null

Deterministic primary parent; null for a root.

parents

string array

All direct parent names when more than one membership exists.

children

object array

Included direct children, each with type and name; device children also have role and optional fabricType. Omitted if empty.

properties

object

Complete modeled property map when detail is full.

Shared racks retain every live parent membership. The primary parent provides compatibility for consumers that display only one placement. Group records precede their included descendants.

Devices and Components

Record type

Required fields

Optional fields

device

type, name, role, parent

parents, fabricType, rack, trayId, mgmt_ipv4, properties

gpu or component

type, name, device

properties

A device's role is unknown when not modeled. Its parent is the primary group name, or null when unavailable in the selected projection. A component's device identifies its owning device; component names such as gpu-0 can repeat across owners.

Modeled attributes retain their stored values. properties is included only for full detail and is an extensible model-property map, not a fixed public schema. Neighbor records have the same shape at both detail levels.

JSON
{
  "type": "neighbor",
  "neighborType": "layer2",
  "from": {
    "device": "leaf-1",
    "fabricType": "east-west",
    "port": "swp1",
    "portType": "service",
    "interfaceRole": "Leaf to North-South"
  },
  "to": {
    "device": "border-leaf-1",
    "fabricType": "north-south",
    "port": "swp49"
  }
}

neighborType is layer2 or nvlink. Each end identifies its device and modeled interface port, which can be null if its name is unavailable. fabricType, portType, and interfaceRole are included only when modeled. Interface role is separate from device role.

Physical neighbor orientation is not a traffic direction. Treat the pair of ends as unordered; their from/to orientation is not a stable key.

BGP Neighbors

A BGP record is directional: from describes a selected device's local endpoint, and to describes its outgoing peer relationship.

Field

Type

Meaning

type

string

Always neighbor.

neighborType

string

Always bgp.

from

object

Local endpoint identity and modeled context.

to

object

Remote endpoint context, or {} when unresolved.

resolved

boolean

An outgoing relationship to a live remote endpoint exists.

peerState

string

Local BGP protocol state, when modeled.

peerType

string

Local endpoint subtype, such as EBGP, when modeled.

state

integer

Legacy relationship state, when present. Not the BGP protocol state.

peerState uses Idle, Connect, Active, Opensent, OpenConfirm, Established, or Unknown. An unrecognized modeled state becomes Unknown; a missing state is omitted.

resolved: true does not guarantee an Established session, a reverse relationship, or a known remote device. A local session remains visible when its peer endpoint or relationship is missing. Remote-only context does not create additional session records for devices outside the page.

Endpoint Identity

Endpoint field

Meaning

device

Owning device name, when known.

vrf

VRF name, without the model's BGP: prefix.

peerId

Configured neighbor address for numbered BGP; local physical interface name for unnumbered BGP.

localAddress

This endpoint's own reported address, not its neighbor identity.

port

Modeled interface attachment, when available. Numbered sessions may use a synthetic BGP interface.

externalPeer

Endpoint address when its owning device is unknown. Does not imply that the peer is outside the administrative fabric.

fabricType, portType, interfaceRole

Device and interface context, when modeled.

Identify a BGP endpoint by (device, vrf, peerId) when those fields are available. Missing identity fields on older or incomplete model rows are omitted, not inferred.

Numbered example: leaf-1's neighbor is 192.0.2.2, not its own 192.0.2.1.

JSON
{
  "type": "neighbor",
  "neighborType": "bgp",
  "from": {"device":"leaf-1","vrf":"default","peerId":"192.0.2.2","localAddress":"192.0.2.1"},
  "to": {"device":"spine-1","vrf":"default","peerId":"192.0.2.1","localAddress":"192.0.2.2"},
  "resolved": true,
  "peerType": "EBGP",
  "peerState": "Established"
}

Unnumbered example: the interface identifies the neighbor. Identical link-local addresses can occur on different endpoints or sessions.

JSON
{
  "type": "neighbor",
  "neighborType": "bgp",
  "from": {"device":"leaf-1","vrf":"default","peerId":"swp1","localAddress":"fe80::1","port":"swp1"},
  "to": {"device":"spine-1","vrf":"default","peerId":"swp49","localAddress":"fe80::1","port":"swp49"},
  "resolved": true,
  "peerType": "EBGP",
  "peerState": "Established"
}

Do not use a link-local address alone as an endpoint key. Do not infer a missing reverse BGP record from the forward record.

Pagination and Consistency

  1. Send a request without a cursor.

  2. Process the returned records.

  3. If complete is false, copy nextCursor into the next request's cursor.

  4. Continue until complete is true.

A cursor has this shape:

JSON
{
  "lastGroupPath": "Pod-1/SU-1/Rack-1",
  "lastDevice": "compute-17"
}

Treat it as an API-owned resume position; do not construct or modify it. Both fields must be nonempty strings, and no additional cursor fields are accepted. Keep scope, fabricType, layers, and detail unchanged during a traversal. deviceLimit may change between pages.

Devices are ordered by hierarchy path and device name. A device reachable through multiple matching paths is counted once, using its lexicographically first matching path before the cursor boundary is applied. A page never splits one device's selected topology data across responses. Resuming continues beyond the recorded group when its remaining devices are exhausted.

The export reads a live, eventually consistent model. Neither a response nor a multi-page traversal is a point-in-time snapshot. Topology or job changes can repeat or omit data between pages. A cursor whose device or hierarchy path no longer matches is rejected with HTTP 400; start a new traversal. Restarting does not establish snapshot isolation.

Hierarchy context repeats across pages, and a physical boundary connection may be encountered from both ends. Use idempotent processing. Scope group identity by ancestry and component identity by owning device; names alone need not be globally unique. For physical connections, normalize the pair of device/port ends. For BGP, preserve direction and the endpoint identity described above.

Entities marked pendingDelete and objects under a pending-delete owner are excluded. Deleted hierarchy paths do not consume page slots; shared racks remain eligible through other live paths. A surviving local BGP session becomes unresolved when its remote endpoint is excluded.

Python Pagination Example

This example requires requests. It writes records as JSON Lines and keeps one response page in memory. It does not deduplicate records across pages.

Python
import json
import os

import requests

base_url = os.environ["MINERVA_URL"].rstrip("/")
body = {"layers": ["east-west", "nvlink"], "deviceLimit": 100}

with requests.Session() as session:
    session.headers.update({
        "X-Api-Key": os.environ["MINERVA_API_KEY"],
        "Accept": "application/json",
    })
    while True:
        response = session.post(
            f"{base_url}/minerva/api/v2/export-topology",
            json=body,
            timeout=(10, 120),
        )
        response.raise_for_status()
        page = response.json()

        for record in page["topology"]["records"]:
            print(json.dumps(record, separators=(",", ":")))

        if page["complete"]:
            break
        body["cursor"] = page["nextCursor"]

NDJSON Response

Set Accept: application/x-ndjson to receive one JSON object per line. The same device limit and cursor rules apply. NDJSON changes serialization; it does not bypass pagination or stream an unlimited database traversal. The service prepares each page before emitting its records.

Line

Record type

Content

First

manifest

cursorScope, layers, detail, and optional fabricType.

Middle

Topology records

The same records as the selected JSON collection, without its envelope.

Last

complete

cursorScope ID string, devicesReturned, nextCursor, and complete boolean.

A complete record terminates one page. Its boolean may be false, indicating that another request is required.

Example of an empty, completed page:

{"type":"manifest","cursorScope":{"id":"request:4bdbca9016c484238d7c","createdAt":"2026-10-05T18:00:00+00:00"},"layers":["east-west"],"detail":"summary","fabricType":"east-west"}
{"type":"complete","cursorScope":"request:4bdbca9016c484238d7c","devicesReturned":0,"nextCursor":null,"complete":true}

Require the final complete line before checkpointing a page. If the connection ends early, discard or idempotently replay that page using the same request cursor. Do not attempt to resume within its record stream.

Errors and Recovery

HTTP status

Meaning

Client action

200

Successful page, including an empty selection.

Process the response and follow pagination metadata.

400

Request validation failed, the cursor no longer identifies a matching device, or the job ID could not be resolved.

Correct the request; restart traversal for a stale cursor.

403

Missing or invalid API key when API authentication is enabled.

Verify deployment credentials. The response body is empty.

503

A model-query failure or a handled failure resolving job context.

Retry transient failures with bounded exponential backoff. Escalate persistent failures.

500

An unexpected server error.

Preserve request context and investigate; do not depend on the error-body shape.

Handled 400 and 503 errors return JSON, including when NDJSON was requested. Error text is diagnostic, not a stable machine-readable code.

JSON
{
  "success": false,
  "error": "fabricType must be east-west or north-south"
}

Check the HTTP status and content type before parsing a stream. A retry is read-only but can observe a newer model state. Retain the same request selection and cursor when retrying a page, subject to cursor validity.

Migration from v1

v2 is a different response contract, not a field-compatible replacement. The v1 endpoint remains separate; consumers must opt in to v2.

v1 behavior

v2 equivalent

Layer-2 map keyed by device name

Typed hierarchy, device, component, and neighbor records.

device_names

scope.devices, plus group and job selectors.

No fabric-type selector

Optional fabricType filter.

limit controls internal batching

deviceLimit controls one client-visible page.

Single response for a full export

Explicit cursor traversal in either JSON or NDJSON.

GPUs embedded on servers

Separate gpu records with an owning device.

success: true and device-role summary

Pagination metadata; no success flag or aggregate role summary.

Last updated: