Updating RCA via API
If your team already has an internal system that captures Root Cause Analysis (RCA) details for an incident — for example, a bot that posts a postmortem summary to Slack — you can push that same content into Oppex programmatically, without anyone needing to open the Oppex UI.
This endpoint only ever writes or overwrites an incident's RCA. It never acknowledges or resolves the incident, and calling it again for the same incident simply updates the RCA that's already there.
Authentication
Requests are authenticated with an API key passed in the X-API-KEY header. See API Keys for how to create one.
Identifying the incident
Your system usually won't know Oppex's own incident id — it knows its own identifier for the alert (a PagerDuty incident id, a New Relic issue id, a Slack message, and so on). So this endpoint accepts either:
incidentId— Oppex's own incident id, if you already have it (for example, from the response of the Post an Incident API).externalId— the source system's own identifier for the alert. This is the field most integrations will use.
Provide at least one. If both are given, incidentId is used.
2
3
4
5
6
7
8
9
-H "Content-Type: application/json"
-H "X-API-KEY: <your-api-key>"
-d '{'
"externalId": "deploy-alerts#1756825563123",
"reasonForAlert": "Disk usage crossed 95% on db-primary",
"actionTaken": "Cleared rotated logs and expanded the volume",
"typeOfFix": "PERMANENT"
'}'
A successful request returns 200 OK with the incident id the RCA was written to.
Request body fields
| Field | Required | Description |
|---|---|---|
incidentId | One of incidentId / externalId | Oppex's own incident id. |
externalId | One of incidentId / externalId | The source system's own identifier for the alert. See Slack message identifiers below for how Slack-originated incidents are identified. |
reasonForAlert | Yes | What triggered the alert. |
actionTaken | Yes | What was done to address it. |
typeOfFix | Yes | PERMANENT or TEMPORARY. Other values are stored, but the incident's RCA then can't be edited in Oppex. |
ticketLink | No | Link to a tracking ticket (Jira, Linear, etc.). Must start with http:// or https://. |
etaForPermanentFix | No | When a permanent fix is expected, if typeOfFix is TEMPORARY. Send an ISO-8601 date-time, such as 2026-10-03T18:00:00Z. |
additionalNotes | No | Anything else worth recording against the incident. |
Long values are shortened, not rejected: reasonForAlert and actionTaken keep their first 2,000
characters, ticketLink 1,000, and additionalNotes 10,000. A note is added to say the text was cut.
Response
{
"success": true,
"statusCode": 200,
"message": "RCA updated successfully",
"data": "8GFB1ADE-1M3C-KJ2QX7PA"
}
data is always the id of the incident the RCA was written to — even if you identified it by externalId, or if that externalId belonged to an alert that was grouped under an earlier incident. In that case, the RCA is written to the original (root) incident, which is the one visible in the Oppex UI.
Slack message identifiers
When an incident originates from Slack, Oppex assigns it an externalId of the form:
<channel-name>#<message timestamp in epoch milliseconds>
For example, a message posted in #prod-alerts becomes prod-alerts#1756825563123. The channel name has no leading #, and it is the name the channel had when it was connected to Oppex: if the channel is renamed later, keep using the old name. If your own system is the one posting the original alert into that Slack channel, it can reconstruct this same value from the channel name and the Slack message's own ts field (multiplied by 1000 and rounded, since Slack's ts is seconds-based) to reference the resulting incident here — no need to look anything up in Oppex first.
Error responses
| Status | When |
|---|---|
400 | Neither incidentId nor externalId was provided. A required RCA field is missing. ticketLink isn't an http(s):// URL. No incident matches the given id. The incident belongs to another workspace. More than one incident matches the given externalId (see below). |
401 | The API key is missing, wrong or disabled (see API Keys). Or the key was sent in a header other than X-API-KEY: this endpoint only reads X-API-KEY. |
500 | Something went wrong in Oppex. Retry. If it keeps happening, contact support with the message. |
Every error response except the API key 401 is JSON, and includes a message explaining exactly what went wrong — surface it directly to whoever is debugging the integration.