Files
nmon/openapi.json
jleung f85c3ef781
Some checks failed
ci / lint (push) Has been cancelled
ci / test (ubuntu-24.04-arm) (push) Has been cancelled
ci / test (ubuntu-latest) (push) Has been cancelled
ci / postgres (push) Has been cancelled
ci / openapi (push) Has been cancelled
M3: Go API per UI contract, embedded UI, openapi compat check, nmon-devtools, live gate + screenshots; M4 WP1 reachability and dependency suppression
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lx9FNLG2CqeBbVGGd9bFsP
2026-10-22 20:34:14 +00:00

2594 lines
68 KiB
JSON

{
"components": {
"schemas": {
"AddDeviceBody": {
"additionalProperties": false,
"properties": {
"addresses": {
"description": "Management addresses; an IPv6 address is preferred over IPv4.",
"examples": [
[
"2001:db8::1"
]
],
"items": {
"type": "string"
},
"minItems": 1,
"type": "array"
},
"create_new": {
"description": "Create a new device although a retired one matches the address or sysName.",
"type": "boolean"
},
"kind": {
"default": "network",
"enum": [
"network",
"vm",
"container",
"check_only"
],
"type": "string"
},
"name": {
"examples": [
"core-sw1"
],
"maxLength": 255,
"minLength": 1,
"type": "string"
},
"reattach": {
"description": "Slug of a retired device to restore instead of creating a new one (its slug and interface IDs come back).",
"type": "string"
},
"role": {
"type": "string"
},
"site": {
"type": "string"
},
"snmp": {
"$ref": "#/components/schemas/SNMPBody",
"description": "Required for kind network."
}
},
"required": [
"name",
"addresses"
],
"type": "object"
},
"DeviceFacets": {
"additionalProperties": false,
"properties": {
"kinds": {
"items": {
"type": "string"
},
"type": "array"
},
"roles": {
"items": {
"type": "string"
},
"type": "array"
},
"sites": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"sites",
"roles",
"kinds"
],
"type": "object"
},
"DeviceList": {
"additionalProperties": false,
"properties": {
"items": {
"items": {
"$ref": "#/components/schemas/DeviceSummary"
},
"type": "array"
},
"page": {
"format": "int64",
"type": "integer"
},
"per_page": {
"format": "int64",
"type": "integer"
},
"total": {
"format": "int64",
"type": "integer"
}
},
"required": [
"items",
"page",
"per_page",
"total"
],
"type": "object"
},
"DeviceRef": {
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"slug": {
"type": "string"
}
},
"required": [
"slug",
"name"
],
"type": "object"
},
"DeviceSummary": {
"additionalProperties": false,
"properties": {
"interfaces_down": {
"description": "Active interfaces that are admin up and not oper up.",
"format": "int64",
"type": "integer"
},
"interfaces_total": {
"description": "Active interfaces, excluded ones left out.",
"format": "int64",
"type": "integer"
},
"kind": {
"enum": [
"network",
"vm",
"container",
"check_only"
],
"type": "string"
},
"last_seen": {
"format": "date-time",
"type": [
"string",
"null"
]
},
"mgmt_ip": {
"type": "string"
},
"name": {
"type": "string"
},
"poll_state": {
"enum": [
"ok",
"degraded",
"backoff"
],
"type": "string"
},
"profile": {
"type": "string"
},
"reachability": {
"enum": [
"up",
"down",
"warning",
"unknown",
"maintenance"
],
"type": "string"
},
"role": {
"type": "string"
},
"site": {
"type": "string"
},
"slug": {
"type": "string"
},
"warnings": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"slug",
"name",
"kind",
"site",
"role",
"mgmt_ip",
"profile",
"reachability",
"poll_state",
"last_seen",
"interfaces_total",
"interfaces_down",
"warnings"
],
"type": "object"
},
"DeviceView": {
"additionalProperties": false,
"properties": {
"addresses": {
"items": {
"type": "string"
},
"type": "array"
},
"created_at": {
"format": "date-time",
"type": "string"
},
"enabled": {
"type": "boolean"
},
"groups": {
"items": {
"$ref": "#/components/schemas/GroupView"
},
"type": "array"
},
"hw_serial": {
"type": "string"
},
"interfaces": {
"items": {
"$ref": "#/components/schemas/InterfaceView"
},
"type": "array"
},
"kind": {
"type": "string"
},
"last_seen": {
"format": "date-time",
"type": [
"string",
"null"
]
},
"mgmt_ip": {
"type": "string"
},
"name": {
"type": "string"
},
"parents": {
"items": {
"$ref": "#/components/schemas/DeviceRef"
},
"type": "array"
},
"poll_state": {
"enum": [
"ok",
"degraded",
"backoff"
],
"type": "string"
},
"profile": {
"type": "string"
},
"reachability": {
"enum": [
"up",
"down",
"warning",
"unknown",
"maintenance"
],
"type": "string"
},
"retired_at": {
"format": "date-time",
"type": [
"string",
"null"
]
},
"role": {
"type": "string"
},
"site": {
"type": "string"
},
"slug": {
"description": "Immutable public key.",
"type": "string"
},
"snmp_version": {
"type": "string"
},
"sys_descr": {
"type": "string"
},
"sys_name": {
"type": "string"
},
"sys_object_id": {
"type": "string"
},
"uptime_seconds": {
"description": "sysUpTime from the hot store; null when unknown.",
"format": "double",
"type": [
"number",
"null"
]
},
"warnings": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"slug",
"name",
"kind",
"site",
"role",
"profile",
"enabled",
"mgmt_ip",
"addresses",
"sys_name",
"sys_object_id",
"sys_descr",
"hw_serial",
"uptime_seconds",
"reachability",
"poll_state",
"warnings",
"last_seen",
"created_at",
"parents",
"groups",
"interfaces"
],
"type": "object"
},
"DiscoverView": {
"additionalProperties": false,
"properties": {
"hardware_replaced": {
"type": "boolean"
},
"identity_reviews_opened": {
"format": "int64",
"type": "integer"
},
"interfaces_matched": {
"format": "int64",
"type": "integer"
},
"interfaces_new": {
"format": "int64",
"type": "integer"
},
"interfaces_retired": {
"format": "int64",
"type": "integer"
},
"interfaces_split": {
"description": "Interfaces that could not be matched one-to-one; both rows are kept and an identity review is open.",
"format": "int64",
"type": "integer"
},
"interfaces_unretired": {
"format": "int64",
"type": "integer"
},
"partial": {
"description": "A table overran its row limit or timeout; its previous result was kept.",
"type": "boolean"
},
"profile": {
"type": "string"
},
"profile_missing": {
"description": "The profile the device asked for when it no longer exists; generic was used.",
"type": "string"
},
"tables": {
"items": {
"$ref": "#/components/schemas/TableView"
},
"type": "array"
},
"warnings": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"profile",
"partial",
"tables",
"interfaces_matched",
"interfaces_new",
"interfaces_retired",
"interfaces_split",
"interfaces_unretired",
"identity_reviews_opened",
"hardware_replaced",
"warnings"
],
"type": "object"
},
"GraphIface": {
"additionalProperties": false,
"properties": {
"device": {
"$ref": "#/components/schemas/DeviceRef"
},
"id": {
"type": "string"
},
"ifalias": {
"type": "string"
},
"ifname": {
"type": "string"
},
"speed_bps": {
"format": "int64",
"type": "integer"
}
},
"required": [
"id",
"ifname",
"ifalias",
"speed_bps",
"device"
],
"type": "object"
},
"GraphP95": {
"additionalProperties": false,
"properties": {
"coverage": {
"description": "Share of the drawn range's 5-minute slots that had data, 0 to 1.",
"format": "double",
"type": "number"
},
"in_bps": {
"format": "double",
"type": [
"number",
"null"
]
},
"out_bps": {
"format": "double",
"type": [
"number",
"null"
]
},
"source": {
"enum": [
"materialised",
"live"
],
"type": "string"
}
},
"required": [
"in_bps",
"out_bps",
"source",
"coverage"
],
"type": "object"
},
"GraphResponse": {
"additionalProperties": false,
"properties": {
"iface": {
"$ref": "#/components/schemas/GraphIface"
},
"p95": {
"$ref": "#/components/schemas/GraphP95"
},
"partial": {
"description": "Stretches of the range where neither store has data.",
"items": {
"$ref": "#/components/schemas/TimeSpan"
},
"type": "array"
},
"series": {
"$ref": "#/components/schemas/GraphSeries"
},
"step_seconds": {
"description": "Step of the newest tier.",
"format": "int64",
"type": "integer"
},
"stitched_at": {
"description": "Where the hourly long-store data ends and raw hot data begins.",
"format": "date-time",
"type": "string"
},
"tier": {
"description": "Tier of the newest data.",
"enum": [
"raw",
"1h"
],
"type": "string"
},
"tiers": {
"description": "Present when two stores answered.",
"items": {
"$ref": "#/components/schemas/GraphTier"
},
"type": "array"
},
"unreliable": {
"type": "boolean"
},
"unreliable_reason": {
"description": "Why the counters are not trusted, e.g. counter_32bit_fast_link.",
"type": "string"
}
},
"required": [
"iface",
"step_seconds",
"tier",
"partial",
"unreliable",
"series"
],
"type": "object"
},
"GraphSeries": {
"additionalProperties": false,
"properties": {
"in": {
"items": {
"$ref": "#/components/schemas/Point"
},
"type": "array"
},
"in_max": {
"items": {
"$ref": "#/components/schemas/Point"
},
"type": "array"
},
"out": {
"items": {
"$ref": "#/components/schemas/Point"
},
"type": "array"
},
"out_max": {
"items": {
"$ref": "#/components/schemas/Point"
},
"type": "array"
}
},
"required": [
"in",
"out"
],
"type": "object"
},
"GraphTier": {
"additionalProperties": false,
"properties": {
"from": {
"format": "date-time",
"type": "string"
},
"step_seconds": {
"format": "int64",
"type": "integer"
},
"tier": {
"enum": [
"raw",
"1h"
],
"type": "string"
},
"to": {
"format": "date-time",
"type": "string"
}
},
"required": [
"from",
"to",
"tier",
"step_seconds"
],
"type": "object"
},
"GroupView": {
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"kind": {
"enum": [
"site",
"customer",
"role",
"custom"
],
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name",
"kind"
],
"type": "object"
},
"IdentityReview": {
"additionalProperties": false,
"properties": {
"candidates": {
"items": {
"$ref": "#/components/schemas/ReviewCandidate"
},
"type": "array"
},
"created_at": {
"format": "date-time",
"type": "string"
},
"device": {
"$ref": "#/components/schemas/DeviceRef"
},
"evidence": {
"description": "What the matcher saw, as key: value lines.",
"items": {
"type": "string"
},
"type": "array"
},
"id": {
"description": "Opaque review identifier.",
"type": "string"
},
"kind": {
"enum": [
"ambiguous_match",
"hardware_replaced",
"reattach_candidate"
],
"type": "string"
}
},
"required": [
"id",
"kind",
"device",
"candidates",
"evidence",
"created_at"
],
"type": "object"
},
"IdentityReviewList": {
"additionalProperties": false,
"properties": {
"items": {
"items": {
"$ref": "#/components/schemas/IdentityReview"
},
"type": "array"
},
"page": {
"format": "int64",
"type": "integer"
},
"per_page": {
"format": "int64",
"type": "integer"
},
"total": {
"format": "int64",
"type": "integer"
}
},
"required": [
"items",
"page",
"per_page",
"total"
],
"type": "object"
},
"InterfaceHit": {
"additionalProperties": false,
"properties": {
"admin_status": {
"format": "int64",
"type": "integer"
},
"device": {
"$ref": "#/components/schemas/DeviceRef"
},
"id": {
"description": "Interface ULID.",
"type": "string"
},
"ifalias": {
"type": "string"
},
"ifdescr": {
"type": "string"
},
"ifname": {
"type": "string"
},
"in_bps": {
"format": "double",
"type": [
"number",
"null"
]
},
"oper_status": {
"format": "int64",
"type": "integer"
},
"out_bps": {
"format": "double",
"type": [
"number",
"null"
]
},
"speed_bps": {
"description": "Link speed in bits per second (ifHighSpeed when set).",
"format": "int64",
"type": "integer"
}
},
"required": [
"id",
"device",
"ifname",
"ifalias",
"ifdescr",
"oper_status",
"admin_status",
"speed_bps",
"in_bps",
"out_bps"
],
"type": "object"
},
"InterfaceList": {
"additionalProperties": false,
"properties": {
"items": {
"items": {
"$ref": "#/components/schemas/InterfaceHit"
},
"type": "array"
},
"page": {
"format": "int64",
"type": "integer"
},
"per_page": {
"format": "int64",
"type": "integer"
},
"total": {
"format": "int64",
"type": "integer"
}
},
"required": [
"items",
"page",
"per_page",
"total"
],
"type": "object"
},
"InterfaceView": {
"additionalProperties": false,
"properties": {
"admin_status": {
"description": "ifAdminStatus: 1 up, 2 down, 3 testing",
"format": "int64",
"type": "integer"
},
"excluded": {
"type": "boolean"
},
"first_seen": {
"format": "date-time",
"type": "string"
},
"has_hc_counters": {
"type": "boolean"
},
"id": {
"description": "Immutable ULID.",
"type": "string"
},
"ifalias": {
"type": "string"
},
"ifdescr": {
"type": "string"
},
"ifhighspeed": {
"description": "megabits per second",
"format": "int64",
"type": "integer"
},
"ifindex": {
"description": "Current ifIndex; may change, the ID does not.",
"format": "int64",
"type": "integer"
},
"ifname": {
"type": "string"
},
"ifphysaddr": {
"type": "string"
},
"ifspeed": {
"description": "bits per second",
"format": "int64",
"type": "integer"
},
"iftype": {
"format": "int64",
"type": "integer"
},
"in_bps": {
"description": "Inbound bits per second over 5 minutes.",
"format": "double",
"type": [
"number",
"null"
]
},
"in_errors_ps": {
"description": "Inbound errors per second over 5 minutes.",
"format": "double",
"type": [
"number",
"null"
]
},
"last_discovered": {
"format": "date-time",
"type": "string"
},
"oper_status": {
"description": "ifOperStatus: 1 up, 2 down, 3 testing, 4 unknown, 5 dormant, 6 notPresent, 7 lowerLayerDown",
"format": "int64",
"type": "integer"
},
"out_bps": {
"format": "double",
"type": [
"number",
"null"
]
},
"out_errors_ps": {
"format": "double",
"type": [
"number",
"null"
]
},
"retired_at": {
"format": "date-time",
"type": [
"string",
"null"
]
},
"unreliable": {
"description": "Counters cannot be trusted (32-bit counters on a fast link); no rate is reported.",
"type": "boolean"
}
},
"required": [
"id",
"ifindex",
"ifname",
"ifdescr",
"ifalias",
"ifphysaddr",
"ifspeed",
"ifhighspeed",
"iftype",
"admin_status",
"oper_status",
"has_hc_counters",
"excluded",
"first_seen",
"last_discovered",
"unreliable",
"retired_at",
"in_bps",
"out_bps",
"in_errors_ps",
"out_errors_ps"
],
"type": "object"
},
"Meta": {
"additionalProperties": false,
"properties": {
"build": {
"description": "Commit the binary was built from.",
"type": "string"
},
"now": {
"description": "Server time, UTC.",
"format": "date-time",
"type": "string"
},
"retention": {
"$ref": "#/components/schemas/Retention"
},
"version": {
"description": "Release version stamped at build time; dev for an unstamped build.",
"type": "string"
}
},
"required": [
"version",
"build",
"retention",
"now"
],
"type": "object"
},
"Point": {
"description": "[unix seconds, bits per second or null].",
"maxItems": 2,
"minItems": 2,
"prefixItems": [
{
"description": "unix seconds",
"type": "number"
},
{
"anyOf": [
{
"description": "bits per second",
"type": "number"
},
{
"type": "null"
}
]
}
],
"type": "array"
},
"PollerDeviceHealth": {
"additionalProperties": false,
"properties": {
"base_interval_s": {
"format": "int64",
"type": "integer"
},
"consecutive_failures": {
"format": "int64",
"type": "integer"
},
"interval_s": {
"description": "Current cadence, backoff included.",
"format": "int64",
"type": "integer"
},
"last_cycle_s": {
"description": "Duration of the last cycle.",
"format": "double",
"type": "number"
},
"last_error": {
"type": "string"
},
"missed_deadlines": {
"description": "Consecutive cycles that ended at the deadline.",
"format": "int64",
"type": "integer"
},
"name": {
"type": "string"
},
"next_cycle": {
"format": "date-time",
"type": [
"string",
"null"
]
},
"profile": {
"type": "string"
},
"slug": {
"type": "string"
},
"state": {
"description": "backoff: healthy but polled slower than its base interval.",
"enum": [
"ok",
"degraded",
"backoff"
],
"type": "string"
},
"varbinds": {
"description": "Varbinds per request right now.",
"format": "int64",
"type": "integer"
}
},
"required": [
"slug",
"name",
"state",
"varbinds",
"interval_s",
"base_interval_s",
"last_cycle_s",
"missed_deadlines",
"consecutive_failures",
"last_error",
"next_cycle",
"profile"
],
"type": "object"
},
"PollerHealth": {
"additionalProperties": false,
"properties": {
"devices": {
"items": {
"$ref": "#/components/schemas/PollerDeviceHealth"
},
"type": "array"
},
"totals": {
"$ref": "#/components/schemas/PollerTotals"
}
},
"required": [
"devices",
"totals"
],
"type": "object"
},
"PollerTotals": {
"additionalProperties": false,
"properties": {
"deadline_misses_per_min": {
"format": "double",
"type": "number"
},
"devices_degraded": {
"format": "int64",
"type": "integer"
},
"pdus_per_min": {
"format": "double",
"type": "number"
},
"timeouts_per_min": {
"format": "double",
"type": "number"
},
"write_queue_capacity": {
"format": "int64",
"type": "integer"
},
"write_queue_depth": {
"description": "Samples waiting in the hot write queue.",
"format": "int64",
"type": "integer"
}
},
"required": [
"pdus_per_min",
"timeouts_per_min",
"deadline_misses_per_min",
"write_queue_depth",
"write_queue_capacity",
"devices_degraded"
],
"type": "object"
},
"Problem": {
"additionalProperties": false,
"properties": {
"detail": {
"description": "Explanation specific to this occurrence.",
"type": "string"
},
"errors": {
"description": "Individual errors, e.g. one per invalid parameter.",
"items": {
"$ref": "#/components/schemas/ProblemDetail"
},
"type": "array"
},
"instance": {
"type": "string"
},
"status": {
"description": "HTTP status code.",
"examples": [
404
],
"format": "int64",
"type": "integer"
},
"title": {
"examples": [
"Not Found"
],
"type": "string"
},
"type": {
"description": "URI reference identifying the problem type; about:blank when absent.",
"type": "string"
}
},
"required": [
"title",
"status"
],
"type": "object"
},
"ProblemDetail": {
"additionalProperties": false,
"properties": {
"location": {
"description": "Where the error occurred, e.g. query.per_page or body.parents.",
"type": "string"
},
"message": {
"description": "Error message text.",
"type": "string"
},
"value": {
"description": "The offending value."
}
},
"required": [
"message"
],
"type": "object"
},
"PutDeviceBody": {
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"name": {
"maxLength": 255,
"minLength": 1,
"type": "string"
},
"parents": {
"description": "Parent device slugs, replacing the current parents.",
"items": {
"type": "string"
},
"type": "array"
},
"role": {
"type": "string"
},
"site": {
"type": "string"
},
"snmp": {
"$ref": "#/components/schemas/SNMPBody",
"description": "Replaces the SNMP credential; secrets are write-only."
}
},
"type": "object"
},
"ResolveBody": {
"additionalProperties": false,
"properties": {
"action": {
"description": "merge: keep one interface and retire the others. keep_both: close the review and leave every row as it is.",
"enum": [
"merge",
"keep_both"
],
"type": "string"
},
"keep": {
"description": "With merge: the interface ULID to keep; it must be one of the review's candidates.",
"type": "string"
}
},
"required": [
"action"
],
"type": "object"
},
"Retention": {
"additionalProperties": false,
"properties": {
"fiveminute": {
"type": "string"
},
"hot": {
"examples": [
"720h0m0s"
],
"type": "string"
},
"long": {
"type": "string"
}
},
"required": [
"hot",
"fiveminute",
"long"
],
"type": "object"
},
"ReviewCandidate": {
"additionalProperties": false,
"properties": {
"iface_id": {
"description": "Interface ULID.",
"type": "string"
},
"ifname": {
"type": "string"
},
"score": {
"format": "double",
"type": "number"
}
},
"required": [
"iface_id"
],
"type": "object"
},
"SNMPBody": {
"additionalProperties": false,
"properties": {
"community": {
"description": "v1 and v2c community.",
"examples": [
"public"
],
"type": "string"
},
"port": {
"description": "UDP port; default 161.",
"format": "int64",
"maximum": 65535,
"minimum": 1,
"type": "integer"
},
"v3_auth_pass": {
"type": "string"
},
"v3_auth_proto": {
"description": "MD5, SHA, SHA224, SHA256 (default), SHA384 or SHA512.",
"type": "string"
},
"v3_context": {
"type": "string"
},
"v3_priv_pass": {
"type": "string"
},
"v3_priv_proto": {
"description": "DES, AES (default), AES192 or AES256.",
"type": "string"
},
"v3_user": {
"description": "v3 user name.",
"type": "string"
},
"version": {
"description": "SNMP version.",
"enum": [
"v1",
"v2c",
"v3"
],
"type": "string"
}
},
"required": [
"version"
],
"type": "object"
},
"TableView": {
"additionalProperties": false,
"properties": {
"detail": {
"type": "string"
},
"name": {
"type": "string"
},
"rows": {
"format": "int64",
"type": "integer"
},
"status": {
"description": "ok, partial (row limit or timeout: previous rows kept), error or skipped.",
"type": "string"
}
},
"required": [
"name",
"status",
"rows"
],
"type": "object"
},
"TimeSpan": {
"additionalProperties": false,
"properties": {
"from": {
"format": "date-time",
"type": "string"
},
"to": {
"format": "date-time",
"type": "string"
}
},
"required": [
"from",
"to"
],
"type": "object"
}
}
},
"info": {
"description": "nmon network monitor API.",
"title": "nmon",
"version": "1.0.0"
},
"openapi": "3.1.0",
"paths": {
"/api/v1/devices": {
"get": {
"description": "Paged, with reachability and interface tallies. state filters on the derived reachability, so it is applied after the other filters.",
"operationId": "list-devices",
"parameters": [
{
"explode": false,
"in": "query",
"name": "site",
"schema": {
"type": "string"
}
},
{
"explode": false,
"in": "query",
"name": "role",
"schema": {
"type": "string"
}
},
{
"explode": false,
"in": "query",
"name": "kind",
"schema": {
"enum": [
"network",
"vm",
"container",
"check_only"
],
"type": "string"
}
},
{
"description": "Substring of name, slug, management address or sysName.",
"explode": false,
"in": "query",
"name": "q",
"schema": {
"description": "Substring of name, slug, management address or sysName.",
"type": "string"
}
},
{
"description": "Reachability.",
"explode": false,
"in": "query",
"name": "state",
"schema": {
"description": "Reachability.",
"enum": [
"up",
"down",
"warning",
"unknown",
"maintenance"
],
"type": "string"
}
},
{
"description": "1-based page number.",
"explode": false,
"in": "query",
"name": "page",
"schema": {
"default": 1,
"description": "1-based page number.",
"format": "int64",
"minimum": 1,
"type": "integer"
}
},
{
"description": "Items per page; at most 1,000.",
"explode": false,
"in": "query",
"name": "per_page",
"schema": {
"default": 100,
"description": "Items per page; at most 1,000.",
"format": "int64",
"maximum": 1000,
"minimum": 1,
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeviceList"
}
}
},
"description": "OK"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Error"
}
},
"summary": "List devices",
"tags": [
"devices"
]
},
"post": {
"description": "Creates the credential, device and addresses, runs seed discovery synchronously (30 s limit) and starts polling. A device that does not answer SNMP is rejected with 502 and nothing is stored.",
"operationId": "add-device",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AddDeviceBody"
}
}
},
"required": true
},
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeviceView"
}
}
},
"description": "Created"
},
"409": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Conflict"
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Internal Server Error"
},
"502": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Bad Gateway"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "RFC 9457 problem details"
}
},
"summary": "Add a device",
"tags": [
"devices"
]
}
},
"/api/v1/devices/facets": {
"get": {
"operationId": "get-device-facets",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeviceFacets"
}
}
},
"description": "OK"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Error"
}
},
"summary": "Distinct site, role and kind values of unretired devices",
"tags": [
"devices"
]
}
},
"/api/v1/devices/{slug}": {
"get": {
"description": "Rates are one batched query to the hot store; they are null when the store is unavailable.",
"operationId": "get-device",
"parameters": [
{
"description": "Device slug.",
"in": "path",
"name": "slug",
"required": true,
"schema": {
"description": "Device slug.",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeviceView"
}
}
},
"description": "OK"
},
"404": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Internal Server Error"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "RFC 9457 problem details"
}
},
"summary": "Get a device, its interfaces with live rates, parents and groups",
"tags": [
"devices"
]
},
"put": {
"description": "Only the fields present change. parents replaces the parent list (by slug) and is rejected with 422 naming the path when it would make a cycle. snmp replaces the credential.",
"operationId": "put-device",
"parameters": [
{
"description": "Device slug.",
"in": "path",
"name": "slug",
"required": true,
"schema": {
"description": "Device slug.",
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PutDeviceBody"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeviceView"
}
}
},
"description": "OK"
},
"404": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Not Found"
},
"409": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Conflict"
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Internal Server Error"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "RFC 9457 problem details"
}
},
"summary": "Edit a device",
"tags": [
"devices"
]
}
},
"/api/v1/devices/{slug}/discover": {
"post": {
"description": "Walks the device synchronously (bounded by the discovery timeout), applies the identity matcher and returns what changed. Admin-only once authentication arrives (M6).",
"operationId": "discover-device",
"parameters": [
{
"description": "Device slug.",
"in": "path",
"name": "slug",
"required": true,
"schema": {
"description": "Device slug.",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DiscoverView"
}
}
},
"description": "OK"
},
"404": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Not Found"
},
"409": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Conflict"
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Internal Server Error"
},
"502": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Bad Gateway"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "RFC 9457 problem details"
}
},
"summary": "Run discovery now",
"tags": [
"devices"
]
}
},
"/api/v1/graph": {
"get": {
"description": "From the hot store when the range lies within hot retention; older data comes from the long store's hourly rollups, and a range that needs both is stitched at stitched_at. Stretches with no data in either store are listed in partial. An unreliable interface returns no series. max=true adds the per-step maximum; p95=true adds the 95th percentile of 5-minute averages, computed live.",
"operationId": "get-graph",
"parameters": [
{
"description": "Interface ULID.",
"explode": false,
"in": "query",
"name": "iface",
"required": true,
"schema": {
"description": "Interface ULID.",
"minLength": 1,
"type": "string"
}
},
{
"description": "Start, RFC 3339. Default one hour before to.",
"explode": false,
"in": "query",
"name": "from",
"schema": {
"description": "Start, RFC 3339. Default one hour before to.",
"format": "date-time",
"type": "string"
}
},
{
"description": "End, RFC 3339. Default now.",
"explode": false,
"in": "query",
"name": "to",
"schema": {
"description": "End, RFC 3339. Default now.",
"format": "date-time",
"type": "string"
}
},
{
"description": "Step in seconds. Default max(60, range/1000) rounded up to whole minutes.",
"explode": false,
"in": "query",
"name": "step",
"schema": {
"description": "Step in seconds. Default max(60, range/1000) rounded up to whole minutes.",
"format": "int64",
"minimum": 1,
"type": "integer"
}
},
{
"description": "Only this direction; the other series is empty.",
"explode": false,
"in": "query",
"name": "dir",
"schema": {
"description": "Only this direction; the other series is empty.",
"enum": [
"in",
"out"
],
"type": "string"
}
},
{
"description": "Also return in_max and out_max, the highest one-minute rate within each step.",
"explode": false,
"in": "query",
"name": "max",
"schema": {
"description": "Also return in_max and out_max, the highest one-minute rate within each step.",
"type": "boolean"
}
},
{
"description": "Also return the live 95th percentile of 5-minute averages.",
"explode": false,
"in": "query",
"name": "p95",
"schema": {
"description": "Also return the live 95th percentile of 5-minute averages.",
"type": "boolean"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GraphResponse"
}
}
},
"description": "OK"
},
"404": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Not Found"
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Unprocessable Entity"
},
"429": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Too Many Requests"
},
"500": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Internal Server Error"
},
"503": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Service Unavailable"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "RFC 9457 problem details"
}
},
"summary": "Bits per second in and out of one interface",
"tags": [
"graph"
]
}
},
"/api/v1/identity-reviews": {
"get": {
"operationId": "list-identity-reviews",
"parameters": [
{
"description": "1-based page number.",
"explode": false,
"in": "query",
"name": "page",
"schema": {
"default": 1,
"description": "1-based page number.",
"format": "int64",
"minimum": 1,
"type": "integer"
}
},
{
"description": "Items per page; at most 1,000.",
"explode": false,
"in": "query",
"name": "per_page",
"schema": {
"default": 100,
"description": "Items per page; at most 1,000.",
"format": "int64",
"maximum": 1000,
"minimum": 1,
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IdentityReviewList"
}
}
},
"description": "OK"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Error"
}
},
"summary": "Open identity reviews, oldest first",
"tags": [
"devices"
]
}
},
"/api/v1/identity-reviews/{id}/resolve": {
"post": {
"description": "merge keeps the chosen interface ID and retires the other rows of the review (their history stays in the metric store under their own IDs). keep_both closes the review without changing any row. Both are audited.",
"operationId": "resolve-identity-review",
"parameters": [
{
"description": "Review identifier.",
"in": "path",
"name": "id",
"required": true,
"schema": {
"description": "Review identifier.",
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResolveBody"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IdentityReview"
}
}
},
"description": "OK"
},
"404": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Not Found"
},
"409": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Conflict"
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Internal Server Error"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "RFC 9457 problem details"
}
},
"summary": "Resolve an identity review",
"tags": [
"devices"
]
}
},
"/api/v1/interfaces": {
"get": {
"description": "q matches ifname and ifalias, case-insensitively, across all devices. Rates are null when unknown or unreliable.",
"operationId": "list-interfaces",
"parameters": [
{
"description": "Substring of ifname or ifalias.",
"explode": false,
"in": "query",
"name": "q",
"schema": {
"description": "Substring of ifname or ifalias.",
"type": "string"
}
},
{
"description": "1-based page number.",
"explode": false,
"in": "query",
"name": "page",
"schema": {
"default": 1,
"description": "1-based page number.",
"format": "int64",
"minimum": 1,
"type": "integer"
}
},
{
"description": "Items per page; at most 1,000.",
"explode": false,
"in": "query",
"name": "per_page",
"schema": {
"default": 100,
"description": "Items per page; at most 1,000.",
"format": "int64",
"maximum": 1000,
"minimum": 1,
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/InterfaceList"
}
}
},
"description": "OK"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Error"
}
},
"summary": "Search interfaces by name or alias",
"tags": [
"interfaces"
]
}
},
"/api/v1/meta": {
"get": {
"operationId": "get-meta",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Meta"
}
}
},
"description": "OK"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Error"
}
},
"summary": "Version, build, retention and server time",
"tags": [
"meta"
]
}
},
"/api/v1/poller/health": {
"get": {
"description": "Rates are over about the last minute; the first call after start may report zero.",
"operationId": "get-poller-health",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PollerHealth"
}
}
},
"description": "OK"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Error"
}
},
"summary": "Poller state of every polled device, with PDU, timeout and queue totals",
"tags": [
"poller"
]
}
},
"/api/v1/query": {
"get": {
"description": "Read-only proxy with a 30 s timeout. A result of more than 100,000 series is rejected with 422.",
"operationId": "query",
"parameters": [
{
"description": "MetricsQL expression.",
"explode": false,
"in": "query",
"name": "q",
"required": true,
"schema": {
"description": "MetricsQL expression.",
"examples": [
"ifHCInOctets"
],
"minLength": 1,
"type": "string"
}
},
{
"description": "Evaluation time: RFC 3339 or Unix seconds. Default now.",
"explode": false,
"in": "query",
"name": "time",
"schema": {
"description": "Evaluation time: RFC 3339 or Unix seconds. Default now.",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"type": "object"
}
}
},
"description": "The store's Prometheus-compatible JSON response, unchanged."
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Internal Server Error"
},
"503": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Service Unavailable"
},
"504": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Gateway Timeout"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "RFC 9457 problem details"
}
},
"summary": "Instant MetricsQL query against the hot store",
"tags": [
"query"
]
}
},
"/api/v1/query_range": {
"get": {
"description": "Same limits as /api/v1/query.",
"operationId": "query-range",
"parameters": [
{
"description": "MetricsQL expression.",
"explode": false,
"in": "query",
"name": "q",
"required": true,
"schema": {
"description": "MetricsQL expression.",
"minLength": 1,
"type": "string"
}
},
{
"description": "Start: RFC 3339 or Unix seconds. Default one hour before to.",
"explode": false,
"in": "query",
"name": "from",
"schema": {
"description": "Start: RFC 3339 or Unix seconds. Default one hour before to.",
"type": "string"
}
},
{
"description": "End: RFC 3339 or Unix seconds. Default now.",
"explode": false,
"in": "query",
"name": "to",
"schema": {
"description": "End: RFC 3339 or Unix seconds. Default now.",
"type": "string"
}
},
{
"description": "Resolution step: a duration such as 30s or a number of seconds.",
"explode": false,
"in": "query",
"name": "step",
"required": true,
"schema": {
"description": "Resolution step: a duration such as 30s or a number of seconds.",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"type": "object"
}
}
},
"description": "The store's Prometheus-compatible JSON response, unchanged."
},
"422": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Unprocessable Entity"
},
"500": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Internal Server Error"
},
"503": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Service Unavailable"
},
"504": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Gateway Timeout"
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "RFC 9457 problem details"
}
},
"summary": "Range MetricsQL query against the hot store",
"tags": [
"query"
]
}
},
"/metrics": {
"get": {
"operationId": "metrics",
"responses": {
"200": {
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
},
"description": "Prometheus text exposition."
},
"default": {
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem"
}
}
},
"description": "Error"
}
},
"summary": "nmon's own metrics in Prometheus text format",
"tags": [
"internals"
]
}
}
}
}