{ "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" ] } } } }