Retrieve measurements, anomaly detections, rare syslogs, and correlated incidents from NVIDIA Minerva through the REST API.
|
Attribute |
Value |
|---|---|
|
Preferred method |
|
|
Query endpoint |
|
|
Alternate transport |
|
|
Request and response format |
|
|
Authentication |
Deployment API key in |
The examples use illustrative devices and UTC windows. Available fields, retained data, and permissions depend on your installation.
Authentication and Headers
Use the HTTPS origin for your installation, without an API path or trailing slash.
export MINERVA_BASE='https://minerva.example.com'
# Set MINERVA_API_KEY through your approved secret-management mechanism.
|
Header |
Value |
|---|---|
|
|
Deployment API key |
|
|
|
|
|
|
Keep API keys outside source files, saved requests, and shared output. Use the certificate trust configuration for your installation.
Use /minerva/api for these requests. Time-series query endpoints do not add a /v2 or /v3 segment.
Discover Datasources and Fields
A datasource identifies a collection in the time-series database. Discover the available collections before you construct a query.
curl --fail-with-body --silent --show-error \
"$MINERVA_BASE/minerva/api/tsdatasources" \
-H "x-api-key: $MINERVA_API_KEY" \
-H 'Accept: application/json'
Datasource entries can contain name and properties. A listed datasource does not establish that every metric exists or contains recent data.
|
Method and path |
Purpose |
|---|---|
|
|
List datasource metadata |
|
|
List model names |
|
|
Read a model definition |
|
|
Read identity and filter fields |
|
|
Read metric definitions |
|
|
Read identity keys |
|
|
Find a model for a time-series name |
|
|
Find a time-series name for a model |
Use returned names in these requests. A model name and datasource name are not necessarily identical.
|
Datasource |
Common contents |
|---|---|
|
|
Cumulus interface measurements, including |
|
|
NVLink interface measurements |
|
|
Device and component measurements |
|
|
Histograms and distributions |
|
|
Events, anomaly summaries, incident summaries, and job events |
|
|
Anomaly index records, including rare-log detections |
|
|
Stored syslog records |
|
|
Hourly event rollups, where configured |
Example: RawBER on a Cumulus Interface
Use this query to examine link quality on one Cumulus interface over an hour. It returns the maximum RawBER value in each minute.
The metric name is rawBer, with a lowercase initial letter. It is a gauge, so do not sum it or calculate counter deltas.
This example selects device leaf-01, interface swp1, and the Cumulus switch measurement source. Replace the device, interface, and interval.
Save this body as rawber-request.json:
{
"query": "select * from timeseries",
"tstype": "groupBy",
"granularity": 60000,
"tsparams": {
"queryType": "groupBy",
"dataSource": "interface_v1",
"intervals": ["2026-10-29T12:00:00Z/2026-10-29T13:00:00Z"],
"granularity": {"type": "duration", "duration": 60000},
"dimensions": ["deviceName", "ifName", "eventSource"],
"filter": {
"type": "and",
"fields": [
{"type": "selector", "dimension": "namespace", "value": "prod"},
{"type": "selector", "dimension": "type", "value": "interface"},
{"type": "selector", "dimension": "eventSource", "value": "switch"},
{"type": "selector", "dimension": "deviceName", "value": "leaf-01"},
{"type": "selector", "dimension": "ifName", "value": "swp1"}
]
},
"aggregations": [
{"type": "doubleMax", "name": "rawBerMax", "fieldName": "rawBer"}
],
"limitSpec": {"type": "default", "limit": 1000},
"context": {"skipEmptyBuckets": true}
}
}
curl --fail-with-body --silent --show-error \
--request POST "$MINERVA_BASE/minerva/api/poststream" \
-H "x-api-key: $MINERVA_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
--data-binary @rawber-request.json > rawber-response.json
The query preserves zero values. A null value means RawBER is unavailable for that result. An absent bucket does not mean zero.
A bucket maximum is not an individual raw sample. Smaller query buckets cannot recover detail lost through prior aggregation.
Request Fields
|
Field |
Meaning |
|---|---|
|
|
Fixed request selector, such as |
|
|
Response format selector. Match |
|
|
Bucket size in milliseconds. Keep it consistent with the query. |
|
|
Datasource name |
|
|
UTC start/end pairs, with an inclusive start and exclusive end |
|
|
Identity fields to retain in each result |
|
|
Device, interface, source, and other scope restrictions |
|
|
Metric calculations within each bucket |
|
|
Result limit and optional ordering for |
The request selector strings are part of the API contract. Preserve their spelling and case.
Metric Response
Measurement results appear in entries[].object.content:
{
"entries": [
{
"object": {
"content": {
"timestamp": "2026-10-29T12:00:00.000Z",
"dimensions": {
"deviceName": "leaf-01",
"ifName": "swp1",
"eventSource": "switch"
},
"measures": {"rawBerMax": 0.000001}
}
}
}
]
}
This illustrative response omits other envelope fields. Use the content timestamp for the measurement bucket, rather than the envelope creation time.
Other Metric Queries
|
Query type |
Purpose |
Limit |
|---|---|---|
|
|
Group measurements by identity fields and time buckets |
|
|
|
Aggregate each bucket without identity grouping |
Time interval and bucket size |
|
|
Rank one dimension within each bucket |
|
|
|
Retrieve stored rows with explicit columns |
|
Use each query type's request fields. For timeseries, omit dimensions and limitSpec. For topN, use dimension, metric, and threshold.
For scan, set resultFormat to list and specify columns. Retain dimensions for response classification.
Add this object to virtualColumns. Include timestamp in columns, but exclude it from dimensions:
{"name": "timestamp", "type": "expression", "expression": "timestamp_format(__time)"}
Use each metric's declared aggregation. Interval-delta counters require sums, gauges require a suitable minimum, maximum, or average, and distributions require their declared calculation.
Retrieve Rare Syslogs and Anomaly Details
Rare syslogs are anomaly detections derived from log messages. They differ from an unrestricted export of stored syslogs.
Send this body to POST /minerva/api/poststream:
{
"query": "select * from mv-anomaly",
"tstype": "groupBy",
"granularity": 1000,
"tsparams": {
"queryType": "groupBy",
"dataSource": "anomaly_v1",
"intervals": ["2026-10-29T12:00:00Z/2026-10-29T13:00:00Z"],
"granularity": {"type": "duration", "duration": 1000},
"dimensions": ["key", "anomalyType"],
"filter": {
"type": "and",
"fields": [
{"type": "selector", "dimension": "deviceName", "value": "leaf-01"},
{"type": "selector", "dimension": "eventType", "value": "Anomaly"},
{"type": "selector", "dimension": "anomalyType", "value": "text"},
{"type": "selector", "dimension": "type", "value": "anomalyRareSyslogPerAppSev"}
]
},
"limitSpec": {
"type": "default",
"limit": 100,
"columns": [
{"dimension": "key", "direction": "ascending"},
{"dimension": "anomalyType", "direction": "ascending"}
]
}
}
}
Save the body as anomalies-request.json, then use the same curl command with that filename.
For other anomaly types, remove the anomalyType and type filters. Retain the device, time interval, and result limit.
This detail query requires groupBy, one interval, and a positive duration. Preserve key and anomalyType in the dimensions.
The API selects anomaly identities from the time-series database and retrieves their full detection records. Missing detail records can reduce the result count.
Anomaly content is an object with fields such as alarmId, alarmType, subType, dimensions, and attrs.
Use attrs.epoch for the detection time in milliseconds since the Unix epoch. Retained dimensions can use names such as DeviceName and Description.
For stored event summaries, use select * from timeseries with raw_v1. Filter eventType to Anomaly, Incident, or eventThreshold as appropriate.
These values are case-sensitive. Summary rows do not replace full detection records or incident membership.
Retrieve Correlated Incidents
Send this body to the same query endpoint:
{
"query": "select * from correlated_alarm",
"tstype": "groupBy",
"granularity": 60000,
"tsparams": {
"queryType": "groupBy",
"dataSource": "raw_v1",
"intervals": ["2026-10-29T12:00:00Z/2026-10-29T13:00:00Z"],
"granularity": {"type": "duration", "duration": 60000},
"dimensions": ["key"],
"filter": {"type": "selector", "dimension": "eventType", "value": "Incident"},
"aggregations": [{"type": "count", "name": "count_Sum"}],
"limitSpec": {"type": "default", "limit": 100}
}
}
Add the scope filters required for your installation. Use one interval, retain key, and keep both granularity values consistent.
To retrieve one incident or event, use its exact returned eventId:
{"query": "select * from event", "eventId": "INCIDENT_ID_FROM_RESPONSE"}
To retrieve the incident's member events:
{"query": "select * from alarm where correlatedAlarmId=INCIDENT_ID_FROM_RESPONSE"}
Replace the identifier without quotes inside the selector string. The optional envelope field group_id restricts members to an exact network graph group.
Membership follows the incident's eventIds. It does not accept an independent time window.
Incident and member-event content is a JSON-encoded string. Decode it once, unlike the object content used for measurements and anomalies:
import json
for entry in response.get("entries") or []:
content = entry["object"]["content"]
if isinstance(content, str):
content = json.loads(content)
print(content)
An incident can include incident.numberEvents and incident.eventIds. Compare returned members with those fields and report missing detail records.
Alternate Transport and Job Scope
GET /minerva/api/stream accepts the same envelope fields as query parameters. Encode tsparams as JSON, then URL-encode each parameter.
curl --fail-with-body --silent --show-error --get \
"$MINERVA_BASE/minerva/api/stream" \
-H "x-api-key: $MINERVA_API_KEY" \
--data-urlencode 'query=select * from timeseries' \
--data-urlencode 'tstype=groupBy' \
--data-urlencode 'granularity=60000' \
--data-urlencode "tsparams=$(jq -c '.tsparams' rawber-request.json)"
Prefer POST for nested or large requests. Both transports return finite JSON responses.
For job-based measurement scope, POST /minerva/api/v1/job accepts {"jobId":"12345","subscriberName":"tenant-01"}.
jobId is required. Without subscriberName, the lookup selects the first matching job identifier, so verify the returned subscriber.
Use the returned devices and a verified job interval to scope the measurement query. This lookup does not itself return historical measurements.
Limits and Errors
Use UTC intervals with inclusive starts and exclusive ends. Keep device and interface filters explicit, and apply the required tenant scope.
A result at its limit can be incomplete. Divide large requests into smaller intervals or disjoint device groups.
The count aggregation counts stored rows. It does not necessarily count original samples, unique detections, or incident members.
Preserve stable identities and deduplicate records when extraction windows overlap. Full anomaly queries do not provide a next-page cursor.
|
Observation |
Action |
|---|---|
|
HTTP 401, 403, redirect, or a login page |
Verify the API key, authorization, and hostname. |
|
HTTP 404 |
Verify the endpoint and installation version. |
|
HTTP error, non-JSON body, or application error |
Treat the request as failed. Preserve its scope for diagnosis. |
|
Empty or null |
Check filters, retention, ingestion, and backend health. |
|
Missing dimensions or measures |
Verify the datasource and field definitions. |
|
Fewer detail records than expected |
Check retained details and missing identities. |
An empty result does not establish that no measurements or detections exist. Retention and collection coverage depend on the installation.
Python Examples
For further examples, see the scripts included in the reference configuration package under minerva-configs/rest-api-examples/.
|
Script |
Purpose |
|---|---|
|
|
Retrieve per-minute RawBER maxima for one Cumulus interface |
|
|
Retrieve rare-syslog detections or other anomaly details |
Use Python 3.10 or later. The scripts require no additional Python packages.
Run these examples from that directory. Set MINERVA_BASE and MINERVA_API_KEY as described above.
python3 query_rawber.py \
--device leaf-01 --interface swp1 \
--start 2026-10-29T12:00:00Z --end 2026-10-29T13:00:00Z \
--bucket-seconds 60 --limit 1000 --output-dir output/rawber
python3 query_anomalies.py \
--kind rare-syslogs --device leaf-01 \
--start 2026-10-29T12:00:00Z --end 2026-10-29T13:00:00Z \
--limit 100 --output-dir output/rare-syslogs
python3 query_anomalies.py \
--kind anomalies --device leaf-01 \
--start 2026-10-29T12:00:00Z --end 2026-10-29T13:00:00Z \
--limit 100 --output-dir output/anomalies
Each script saves the request, response, and CSV results. Add --dry-run to inspect a request without credentials or a network call.
Last updated: