What each metric measures — the dictionary behind a bare metric name (ADR-079 decision 4).
const url = 'https://example.com/api/v1/metric-meanings';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/metric-meanings \ --header 'Authorization: Bearer <token>'No Admin extractor and no 503. The table is compiled in, so this answers identically in
skeleton mode and on a public dashboard; requiring the write side would refuse a question that
needs no database.
⚠️ The WebUI does not call this, and that is deliberate rather than an oversight. The screen
needs the sentence in the operator’s language and synchronously during render, so it reads the
i18n bundle — whose English half is generated from the very same table. The documented consumers
are the OpenAPI contract and the get_config(kind=metric_meanings) MCP tool, which is the whole
reason the route exists: before it, “what does icmp_loss_pct measure” was a question the alert
rules table answered and /mcp could not.
Authorizations
Section titled “Authorizations”Responses
Section titled “Responses”Every metric Yagra can explain, sorted by metric name, each with where its number comes from. Static vocabulary — it does not depend on what this deployment collects
One metric and what it measures, in one sentence.
object
What an alert on this metric is called, in English — SNMP not responding rather than
snmp_up (ADR-196). Every alert response carries the same words as its title.
true when the metric is a 0/1 answer, so alert_name names the fault itself and the
threshold and observed value say nothing a reader needs; false when the name is a noun
the condition and value follow.
Which of Yagra’s own probes emits a check metric — icmp, snmp, url, dns or
meraki — and null for every other source (ADR-046 Inc.8). snmp here means the SNMP
conversation itself (did the agent answer, how far the walk got, what it found), not a
value read off a MIB; those are collected. The node Overview files its cards by this.
One sentence, in English. English is canonical (crate::metric_meaning); the WebUI renders
a translation of it, so the wording here and the wording on screen may differ by language,
never by content.
Stable metric name — the same spelling a threshold rule’s metric and a TSDB series use.
Where the number comes from: check (one of Yagra’s own probes), derived (computed per
port at evaluation time, and therefore present in no time series — asking
query_metrics for it returns nothing), or collected (read off a device by a metric set,
with its OID in get_config(kind=mib_catalog)).
The unit the stored number is in, or null when it has none (ADR-046 Inc.7).
⚠️ Stored, not displayed. query_metrics returns the stored value and a threshold bound
is written in the stored unit, so that is the one served here. When unit_kind is scaled
the WebUI shows something else — hundredths of a second is drawn as 1mo 9d 02:09, and
kilobytes as 15.6 GB — and the number you would write in a rule is still the stored one.
How to read unit: symbol (append it — %, ms, °C), counted (the noun being
counted — sessions, users), scaled (the stored unit, spelled out, of a value the
WebUI rescales before showing), or null when the metric has no unit.
Separate from unit because the payloads are not distinguishable by inspection: % and
kilobytes are both strings, and appending one to a number is correct while appending the
other is not.
Examplegenerated
[ { "alert_name": "example", "alert_name_is_flag": true, "family": "example", "meaning": "example", "metric": "example", "source": "example", "unit": "example", "unit_kind": "example" }]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 read permission
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" }}