The threshold rules that reach one port (ADR-076 decision 11).
const url = 'https://example.com/api/v1/nodes/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/interfaces/1/thresholds';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://example.com/api/v1/nodes/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/interfaces/1/thresholds \ --header 'Authorization: Bearer <token>'A port is governed by rules at six scope levels, and the narrow ones are usually not where the interesting rule lives — a fleet-wide “any link over 90%” is a global rule, and a page that listed only the port’s own rules would show an empty list about a port that is alerting.
Rules come from PostgreSQL on every call rather than from the alert engine’s snapshot, which refreshes on the config generation: a rule saved a second ago is not in that snapshot, and the operator who just pressed Save is precisely the caller of this endpoint. The node’s own metadata (profile, tag values, folder chain) does come from the snapshot — it is what decides whether a broad rule reaches this node, and it does not change under the operator’s hand.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Node id
SNMP ifIndex of the interface
Responses
Section titled “Responses”Every rule that reaches this port, from any scope level, most specific first, each flagged with whether it is in force
One rule that reaches a port, and whether it is the one in force there.
object
Whether this rule sits at the winning scope level for its metric — the most specific level that reaches this port, and among folder-group rules only the nearest group in the chain (ADR-013 + ADR-075 decision 11).
Several rules can carry true for one metric at once: the engine merges rules at the
winning level by keeping the more restrictive bound of each severity. So this means “this
rule contributes to the effective bound”, not “this rule is the effective bound”.
The stored rule, in the same shape the rules list serves.
object
Value at/above which the node is Critical. None = no upper critical bound.
Value at/below which the node is Critical. None = no lower critical bound.
Hysteresis: consecutive samples the breach must hold before transitioning,
to damp oscillation at the threshold. 0/1 = transition immediately.
Stable metric name this rule applies to (e.g. cpu_util).
Value at/above which the node is Warning. None = no upper warning bound.
Value at/below which the node is Warning. None = no lower warning bound.
The primary side’s critical bound. See direction.
Which way this rule’s warning/critical face. Superseded by the four bounds on the rule
itself, which describe both sides; on a rule bounding both, this names the primary side
only and describes half of what the rule does.
Which rows of a vendor table this rule applies to, by the row’s name — I/O, or
MPU Board *. Case-insensitive, and * matches any run of characters. Absent means every
row, and every metric that has no rows. At the same scope, a rule with a pattern wins over
one without for the rows it matches.
Every profile, folder group, node or port this rule applies to — scope_level says which
of those they are. Empty for a global rule, which applies to every node.
The scope a threshold is defined at, ordered least → most specific: Interface (one port)
wins over Node, which wins over a folder group, which wins over Group, which wins over
Profile, which wins over Global (every node).
The primary side’s warning bound. See direction.
Example
[ { "rule": { "direction": "above", "scope_level": "global" } }]No valid bearer token
The ADR-019 envelope every failure renders as. pub(crate) and schema-bearing so the OpenAPI
document can name one error shape for every endpoint (ADR-035) instead of leaving 4xx/5xx bodies
undescribed — a client that has to guess the failure shape ends up parsing the success shape and
reading undefined.
object
object
Stable machine-readable code. Clients branch on this, never on the message.
Operator-facing sentence. Safe to display; never carries an internal error’s own text.
Examplegenerated
{ "error": { "code": "example", "message": "example" }}Role lacks ManageConfig, or the node is outside the token’s group scope
The ADR-019 envelope every failure renders as. pub(crate) and schema-bearing so the OpenAPI
document can name one error shape for every endpoint (ADR-035) instead of leaving 4xx/5xx bodies
undescribed — a client that has to guess the failure shape ends up parsing the success shape and
reading undefined.
object
object
Stable machine-readable code. Clients branch on this, never on the message.
Operator-facing sentence. Safe to display; never carries an internal error’s own text.
Examplegenerated
{ "error": { "code": "example", "message": "example" }}Skeleton mode has no write side
The ADR-019 envelope every failure renders as. pub(crate) and schema-bearing so the OpenAPI
document can name one error shape for every endpoint (ADR-035) instead of leaving 4xx/5xx bodies
undescribed — a client that has to guess the failure shape ends up parsing the success shape and
reading undefined.
object
object
Stable machine-readable code. Clients branch on this, never on the message.
Operator-facing sentence. Safe to display; never carries an internal error’s own text.
Examplegenerated
{ "error": { "code": "example", "message": "example" }}