Skip to content

Interfaces discovered on a node, with query-time utilization.

GET
/api/v1/nodes/{node_id}/interfaces
curl --request GET \
--url https://example.com/api/v1/nodes/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/interfaces \
--header 'Authorization: Bearer <token>'

View, not ManageConfig — unlike the rest of this module. An interface list is device state an operator reads, not a setting they author. Skeleton mode answers an empty list rather than 503: the interface inventory is PostgreSQL-only, so “none known” is the truthful answer.

node_id
required
string format: uuid

Node id

Interfaces known for this node with query-time utilization; empty in skeleton mode

Media typeapplication/json
Array<object>

One interface row for the node-detail Interfaces tab: stored metadata joined with query-time rate()/latest() metrics. Utilization is derived here and never stored (ADR-012).

The four *_power_*_dbm bounds are the transceiver’s own acceptable window, as the module reports it — not a threshold anyone configured in Yagra, and nothing alerts on them. They exist so a client can say whether a light level is healthy, which a bare dBm figure cannot: −7 dBm is fine on one module and failing on another. They are null for every interface that is not optical, and also for optical ones whose vendor dialect publishes no thresholds — ENTITY-SENSOR -MIB (RFC 3433) defines none at all, so a standards-based agent reports power without a window. A pair the module reported implausibly (low above high, or outside a transceiver’s physical range) is dropped by the poller rather than passed on, because a wrong window accuses a healthy link. Same units as the readings: dBm, normally negative (ADR-062 Inc.4).

if_duplex and if_type describe the physical link (ADR-063 Inc.1). if_duplex is half or full as the device negotiated it, and null whenever that is not known — which covers a device that does not implement EtherLike-MIB, a port that is down and so has negotiated nothing, and a device answering unknown. ⚠️ Expect null on optical ports and do not read it as a fault: IEEE 802.3 defines no half duplex above 1 Gbit/s, so there is nothing to negotiate. The field earns its place on copper, where a duplex mismatch is a real misconfiguration. if_type is the IANAifType integer (6 = ethernetCsmacd); it is what distinguishes “duplex does not apply to this interface” — a loopback, a tunnel, a dialer — from “we could not read it”.

addresses lists every IP address configured on the interface — secondaries included — as the device reports them in its IP address tables (ADR-157). Read from the hourly address walk (ADR-043), so a change shows within an hour; empty until that walk has run, and for a port the device reports no address on. An address the device attributes to no interface is not listed.

object
addresses
required
Array<object>

One IP address configured on an interface, as the device reports it (ADR-157).

Every address the device lists is here, in a fixed order (IPv4 before IPv6, numeric within each), so a secondary is as visible as the primary — SNMP does not say which is which.

object
ip
required

The address itself, in its usual text form; never narrowed to IPv4.

string
prefix_len

Prefix length in bits (24 for a /24). null when the device gave a mask or prefix that could not be decoded — the address is still real, only its network is unknown.

integer | null format: int32
if_alias
string | null
if_duplex
string | null
if_media
string | null
if_name
string | null
if_speed_bps
integer | null format: int64
if_type
integer | null format: int32
ifindex
required
integer format: int32
in_bps
number | null format: double
in_util_pct
number | null format: double
last_seen_unix
integer | null format: int64
oper_status
number | null format: double
out_bps
number | null format: double
out_util_pct
number | null format: double
rx_power_high_dbm
number | null format: double
rx_power_low_dbm
number | null format: double
stale
required
boolean
transceiver_model
string | null
tx_power_high_dbm
number | null format: double
tx_power_low_dbm
number | null format: double
Examplegenerated
[
{
"addresses": [
{
"ip": "example",
"prefix_len": 1
}
],
"if_alias": "example",
"if_duplex": "example",
"if_media": "example",
"if_name": "example",
"if_speed_bps": 1,
"if_type": 1,
"ifindex": 1,
"in_bps": 1,
"in_util_pct": 1,
"last_seen_unix": 1,
"oper_status": 1,
"out_bps": 1,
"out_util_pct": 1,
"rx_power_high_dbm": 1,
"rx_power_low_dbm": 1,
"stale": true,
"transceiver_model": "example",
"tx_power_high_dbm": 1,
"tx_power_low_dbm": 1
}
]

No valid bearer token

Media typeapplication/json

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
error
required
object
code
required

Stable machine-readable code. Clients branch on this, never on the message.

string
message
required

Operator-facing sentence. Safe to display; never carries an internal error’s own text.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}

Role lacks View

Media typeapplication/json

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
error
required
object
code
required

Stable machine-readable code. Clients branch on this, never on the message.

string
message
required

Operator-facing sentence. Safe to display; never carries an internal error’s own text.

string
Examplegenerated
{
"error": {
"code": "example",
"message": "example"
}
}