コンテンツにスキップ

get_node

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

Node id

The node’s configuration, bindings and resolved kind

Media typeapplication/json

One node’s configuration detail, including its bindings (profile/credential/parent) so the node-detail page can show and edit them. Live mode only (PostgreSQL inventory).

object
address
required

The node’s address; 0.0.0.0 (or ::) means it has none (see NodeSummary.address).

string
credential_id
string | null format: uuid
dns_check
One of:
null
group_id

The group this node belongs to; null ⇒ ungrouped.

string | null format: uuid
id
required

Stable identifier for a monitored node.

A UUID, not a name or address — both of which can change over a node’s life.

string format: uuid
inherited_tags
required

The labels this node gets from its inventory folder and that folder’s ancestors, already minus the ones it excludes and minus anything it carries itself (ADR-135 inc. 2). Sorted.

Resolved on every read and never stored — a copy written onto the node row would go stale the moment a parent is edited or a folder is moved, which is the same call folder-pool and map-coordinate inheritance already made.

The screen draws tags and these as two marked groups; a chip here is removed by adding it to tags_excluded, not by editing tags.

Array<string>
kind
required

What this node is — the kind the scheduler actually polls it as, resolved by the one precedence in [NodeKind::resolve].

The three configs below are the raw rows, and a node is not guaranteed to carry only one: the API edge refuses a second, but rows predating that guard exist. Reading the configs and concluding a kind from whichever is non-null is how the node page came to show a URL-monitor health card for a node the poller was treating as a Meraki device. Branch on this instead.

string
Allowed values: wireless_ap meraki url dns device
meraki_device
One of:
null
meraki_pair
One of:
null
meraki_repeater

true when the Meraki device is a mesh repeater — an access point with no wired uplink, whose address is therefore 0.0.0.0 (ADR-175). Absent otherwise.

boolean
meraki_site
One of:
null
model
string | null
name
required
string
notes

The operator’s free-text note about this node; null ⇒ none (ADR-135).

⚠️ Detail only — deliberately not on NodeSummary. The inventory tree fetches one summary per node and ADR-133 had just made that response smaller; a note is up to 2,000 characters that the tree does not draw.

string | null
os_version

The OS / software version the device last reported over SNMP (ADR-138), e.g. 15.0(2a)EX5; null ⇒ never read — the node is not SNMP-polled, the version table does not cover the device, or the poller that owns it predates the field.

⚠️ Observed, not configured. Nothing writes it but the poll path: the poller re-reads it hourly, so it can trail an upgrade by up to an hour, and a poll that cannot read it leaves the last value in place. Detail-only, like notes.

string | null
parent_id
string | null format: uuid
pool

The node’s own poll-pool (ADR-009/020); null ⇒ it inherits from its folder, else the default pool. Deliberately the raw stored value, not the effective one, so the edit form can tell an explicit assignment from an inherited one — the effective pool (and which poller currently holds the node) comes from GET /nodes/:id/assignment.

string | null
profile_id
string | null format: uuid
profile_locked
required

Whether a person fixed this node’s profile (ADR-140). A locked node is never offered on Nodes ▸ Reclassify; the edit dialog is where it is set and cleared. Detail-only.

boolean
serial_number

The device’s serial number (ADR-147), e.g. FCW1929B68S; a stack lists every member in order, joined with , . For an SNMP device it is the serial of each chassis in ENTITY-MIB, read hourly; for a Meraki device it is the serial the node was imported with. null ⇒ not known — the device keeps no chassis serial in ENTITY-MIB, or it has not been read yet.

⚠️ Observed, not configured, like os_version: it can trail a chassis swap by up to an hour, and a read that fails leaves the last value in place. Detail-only.

string | null
snmp_configured
required

Whether SNMP polling is configured for this node — not whether it is answering.

🚨 Do not re-derive this from credential_id. The scheduler falls back to the deployment-wide YAGRA_SNMP_COMMUNITY for every node with no bound credential, so on such a deployment a credential_id of null still means a device that is walked, has interface rows and has neighbours. The WebUI uses this to hide the tabs whose only data source is an SNMP walk (Interfaces, Neighbors — ADR-119); deriving it client-side would hide them on exactly the nodes that have the data.

⚠️ Over-reports rather than under-reports — see PollDispatcher::snmp_configured_for, which is the one place the rule lives.

boolean
tags
required

The labels stored on this node (ADR-135). Empty when it has none, sorted.

Also detail-only, and for a second reason beyond size: the tree does not display them, and NodeSummaryDto on the MCP side has carried them since before any writer existed.

⚠️ This is what the edit dialog writes back, so it is the node’s OWN set — not what it effectively carries. The inherited half is inherited_tags below.

Array<string>
tags_excluded
required

Labels this node refuses to inherit (ADR-135 inc. 2). Sorted.

Shown in full, including entries naming a label nothing currently supplies: an exclusion that cannot be seen cannot be undone, and it stays meaningful because an ancestor may re-add that label later.

Array<string>
url_check
One of:
null
vendor

Descriptive maker/model, editable from the node detail.

string | null
wireless
One of:
null
Example
{
"dns_check": {
"record_type": "A"
},
"kind": "wireless_ap",
"meraki_pair": {
"partner": {
"node_state": "ok",
"role": "primary"
},
"role": "primary",
"state": "normal"
},
"url_check": {
"body_match": {
"mode": "contains"
},
"expected_status": {
"kind": "two_xx"
},
"method": "GET"
},
"wireless": {
"ap": {
"reported_by": [
{
"state": "associated"
}
],
"state": "associated"
},
"controller": {
"flavor": "huawei"
}
}
}

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 the View permission

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

No such node, or this deployment has no inventory

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