Generate (or serve from cache) an explanation of one incident.
const url = 'https://example.com/api/v1/rca';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"check":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","force":true,"language":"example","node":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","window_secs":1}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/api/v1/rca \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "check": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "force": true, "language": "example", "node": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "window_secs": 1 }'Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”The POST /api/v1/rca body.
object
Regenerate instead of serving a cached report. Still rate-limited.
UI language tag (ja, en-GB, …). The instructions stay English; the answer follows the
reader. Unknown tags fall back to English rather than failing.
The alerting node. May be a symptom of an upstream failure — the context builder follows
root_cause to the incident before assembling anything.
Timeline window in seconds; clamped by the orchestrator. Defaults to an hour.
Examplegenerated
{ "check": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "force": true, "language": "example", "node": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "window_secs": 1}Responses
Section titled “Responses”The explanation and the evidence it was grounded in
A stored report. body carries the answer and its evidence; summary is lifted out of it so a
list view does not have to fetch the whole thing.
object
The answer and the evidence it was grounded in.
object
The parsed explanation. Every field is plain text and must be rendered as text, never as HTML or markdown — this is model output, and the model was itself reading untrusted device output.
object
How sure the model says it is.
Whether the other affected nodes are consequences of it.
Concrete things to check next.
Set when the reply was not parseable JSON: the model’s text, verbatim and bounded. Its presence is what tells the UI to render one prose block rather than empty sections.
What most likely failed, and why the evidence says so.
One sentence an on-call engineer can act on.
Everything the model was told, exactly as it saw it.
object
The alert on that node.
object
Set when the operator clicked a symptom and the context hopped to its cause. Naming the node they clicked keeps the answer connected to what they were looking at.
Whether the engine is damping this check as flapping. Worth telling the model: a flapping link and a hard failure have different causes and different next steps.
What the check measured — icmp_rtt_ms, or the liveness sentinel.
Alerts rolled up under this one.
object
The named dependents, capped — see total for how many there actually are.
How many there are in total — kept separately so truncation is visible rather than silent.
When the context was assembled (Unix seconds), so the prompt can express ages rather than absolute times the model has no clock for.
The node being explained — the root cause, after any roll-up hop.
object
Poller pool — usually the site, which is often the diagnosis (“everything in branch-osaka”).
Operator-set grouping attributes, capped and sorted for a deterministic prompt.
Recent audited configuration changes touching this node.
One audited configuration change.
object
"{METHOD} {path}", as recorded by the audit middleware.
Id of the node being explained. Differs from the one the operator clicked whenever the roll-up hop fired, and it is what a generated report is filed under — a report explains the cause, so it belongs to the cause.
Cross-signal timeline for the window, oldest first.
One dated signal on an incident timeline (incident_correlate).
Serialize because an RCA report stores the timeline it was grounded in alongside the answer:
the UI shows the two together so a reader can check the explanation against its evidence rather
than taking it on faith (ADR-029).
object
Inventory ancestors, nearest first. Present even when healthy: “the parent is fine” is evidence that the failure is local to this node.
The subset of a node the model may see. Notably not the credential binding.
object
Poller pool — usually the site, which is often the diagnosis (“everything in branch-osaka”).
Operator-set grouping attributes, capped and sorted for a deterministic prompt.
How far back the timeline reaches.
Which language the answer was requested in.
What the model looked up for itself, in order (ADR-028 WS-G). Empty on a single-shot run, and on every report written before agentic retrieval existed.
One tool the model asked for, and what it was told.
Stored for the same reason evidence is: an explanation whose reader cannot check what it was
based on is an assertion. Agentic retrieval makes that worse, not better — the evidence is no
longer a fixed set somebody chose, so without this nobody can tell whether the model looked at
the right thing.
object
The arguments the model chose.
object
What the tool answered, as the model saw it.
The tool name, from the agent’s allow-list.
Whether this response came from the cache rather than a fresh call. Not a column — it describes this delivery of the report, not the report.
Example
{ "body": { "answer": { "confidence": "high" }, "evidence": { "alert": { "breach": { "direction": "above" } } }, "language": "en" }}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 the AckAlerts 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" }}No incident matches that node and check
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" }}Rate or concurrency cap reached; carries Retry-After
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" }}The provider failed or the model refused
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, or no LLM provider configured / configured wrongly
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" }}