Skip to main content

Generic Webhook

The Generic Webhook accepts alerts from any monitoring tool or script that can post JSON. You map your tool's payload to a few Oppex fields, and request headers tell Oppex which statuses create incidents, which resolve them, and what severity to use. The Datadog and Splunk pages are worked set-ups of this webhook.

Before you start​

You need the following:

  • An Oppex API key from the workspace that owns the service. Open Settings, and in your workspace's section click API Keys. If your organization has only one workspace, click Organization → API Keys instead. See API Keys to create one. One key can serve several tools.
  • The service's integration key, to send alerts to one service. The Generic Webhook guide's sample request contains it, as described in step 1.
  • A tool that can send custom headers. If your tool cannot, it can send the API key with HTTP Basic authentication instead, as described in "Authenticate without custom headers".

Step 1: Open the Generic Webhook guide in Oppex​

  1. Open Services.
  2. In the service's row, click Integration Details and select Generic Webhook.
  3. Copy the Webhook URL from Build the webhook payload, and the service key from the sample request in Test your integration.

The webhook URL is the same for every service:

https://api.oppex.ai/integrations/webhook/incident/generic

Step 2: Configure the request headers​

Oppex uses request headers to authenticate the request and to decide how it handles each alert.

HeaderRequiredDescription
X-GE-API-KEYYesYour Oppex API key
X-GE-SOURCEYesThe label shown as the incident's source, for example Generic
X-GE-AUTORESOLVENoSet to true to resolve incidents when a resolved status arrives
X-GE-STATUS-TRIGGEREDNoComma-separated statuses that create incidents, for example DOWN,CRITICAL. If absent, every request creates an incident
X-GE-STATUS-RESOLVEDNoComma-separated statuses that resolve incidents, for example UP,OK
X-GE-STATUS-SEVERITYNoA JSON map of status to severity, for example {"CRITICAL": 1, "HIGH": 2, "MEDIUM": 3, "LOW": 4}. The body's severity field takes precedence
Step 2 of the in-app guide, Configure request headers, listing the six headers, a severity map example, and a note that the group field is required for auto-resolve

Status lists are matched as exact values, ignoring letter case.

Auto-resolve works only with a recognised source label

Oppex links a resolved status to its incident through the group field only for sources it recognises. Set X-GE-SOURCE to Generic to use auto-resolve. With a custom label such as MyMonitor, Oppex drops the group: resolved statuses cannot find the incident and are rejected with "No open incidents found for group", and repeated alerts open new incidents. To use your own label with auto-resolve, contact Oppex support.

Step 3: Build the payload​

Post a JSON body to the webhook URL with Content-Type: application/json. Every field is a top-level key.

FieldRequiredDescription
titleYes, to create an incidentThe incident title
statusYes, when you use status headersCompared with X-GE-STATUS-TRIGGERED and X-GE-STATUS-RESOLVED. If absent, Oppex reads state
serviceKeyNoSends the incident to this service. Without it, the workspace's service routing chooses
groupYes, for auto-resolveIdentifies one problem. A resolved status resolves the incidents with the same group
severityNoCRITICAL, HIGH, MEDIUM or LOW, or a number from 1 to 5
srcTimestampNoWhen the alert happened, in epoch milliseconds, as a number or a string of digits
tenantNoA tenant name
typeNoThe incident type
externalIDNoThe alert's ID in your tool
componentNoThe affected component
detailsJSONNoExtra context, as a JSON string
Step 3 of the in-app guide, Build the webhook payload, with the webhook URL for the Pit Wall API service and the table of payload fields
Put serviceKey in the body

The in-app guide says that you can pass serviceKey either as a URL parameter or in the body. For the Generic Webhook, only the body works. A serviceKey in the URL is not used, and the incident goes to the service that your workspace's service routing chooses.

Any other field in your payload is kept in the incident's details. Nothing you send is discarded, so you can include your tool's own fields, such as a link back to the alert.

Timestamps must be epoch milliseconds

srcTimestamp accepts epoch milliseconds only. Oppex ignores an ISO-8601 time in this field and records the time it received the alert instead. A value in epoch seconds is read as milliseconds, which places the alert in 1970.

How Oppex handles each request​

Oppex checks each request in this order:

  1. If X-GE-AUTORESOLVE is true and the status is in X-GE-STATUS-RESOLVED, Oppex resolves the incidents with the same group. The request must include group.
  2. Otherwise, if X-GE-STATUS-TRIGGERED is absent, or the status is in it, Oppex creates an incident.
  3. Otherwise, Oppex ignores the request.

The severity comes from the first of these that has a value:

  1. The body's severity field. Text values other than CRITICAL, HIGH, MEDIUM and LOW are skipped.
  2. The status's entry in X-GE-STATUS-SEVERITY.
  3. Severity 1.

While an incident is open, another alert with the same group attaches to it instead of opening a new incident. See Grouping strategy.

Resolution matches the group across your organization

A resolved status resolves every open incident in your organization with the same group, not only incidents on this service. Use group values that identify one problem, such as a host and check name, rather than a broad value such as production.

Step 4: Test the integration​

Send a sample alert. Replace the two keys first.

curl -X POST "https://api.oppex.ai/integrations/webhook/incident/generic" \
-H "Content-Type: application/json" \
-H "X-GE-API-KEY: YOUR_API_KEY" \
-H "X-GE-SOURCE: Generic" \
-H "X-GE-AUTORESOLVE: true" \
-H "X-GE-STATUS-TRIGGERED: DOWN,CRITICAL" \
-H "X-GE-STATUS-RESOLVED: UP,OK" \
-d '{"title":"Box Box: Pit Wall API latency above 2 s","status":"DOWN","serviceKey":"YOUR_SERVICE_KEY","group":"pit-wall-latency","severity":"CRITICAL","srcTimestamp":1791460800000,"type":"Infrastructure","externalID":"RC-12345","component":"pit-wall-api","driver":"car-44"}'

Oppex replies "Incident created successfully", and a Severity 1 incident appears on the Incidents page. The driver field appears in the incident details. Send the same request with "status":"UP" to resolve it.

If a request fails, the reply tells you why:

ReplyCause
X-GE-API-KEY header is requiredNo API key was sent
X-GE-SOURCE header is requiredThe source header is missing
Field 'title' is required in payloadA request that creates an incident has no title
Field 'group' is required for auto-resolveA resolved status arrived without group
No open incidents found for groupNo open incident has that group, or the source label is not recognised
Status not in triggered or resolved states — ignoredThe status is in neither list. No incident is created
Invalid Service KeyThe serviceKey does not match a service
Unexpected processing errorThe API key is not a valid Oppex API key

Authenticate without custom headers​

Some tools cannot set custom headers. Such a tool can send the API key with HTTP Basic authentication instead: use any username, and your Oppex API key as the password. The source label can then go in the URL:

https://api.oppex.ai/integrations/webhook/incident/generic?source=Generic

A source in the URL takes precedence over X-GE-SOURCE. Oppex rejects a request whose basic authentication password is not a valid, enabled API key, with the reply "Invalid API key". Without status headers, every request with a title creates an incident, and nothing resolves automatically.

In-product guide​

Oppex shows the same headers, payload fields and a sample request inside the product, with your service's integration key filled in. Open Services, click Integration Details in the service's row, and select Generic Webhook.

FAQ

Which tools can use the Generic Webhook?

Any tool or script that can post JSON over HTTPS. To set statuses and auto-resolve, the tool must also send custom headers.

Why did a resolved status not resolve my incident?

Check that X-GE-AUTORESOLVE is true, that the request carries the same group as the incident, and that X-GE-SOURCE is Generic. A custom source label drops the group.

What severity does an incident get if I send none?

Severity 1, unless X-GE-STATUS-SEVERITY maps the alert's status to another severity.

What happens to fields Oppex does not recognise?

Oppex keeps them in the incident's details, so responders can see them on the incident.

In this article

FAQ

Which tools can use the Generic Webhook?

Any tool or script that can post JSON over HTTPS. To set statuses and auto-resolve, the tool must also send custom headers.

Why did a resolved status not resolve my incident?

Check that X-GE-AUTORESOLVE is true, that the request carries the same group as the incident, and that X-GE-SOURCE is Generic. A custom source label drops the group.

What severity does an incident get if I send none?

Severity 1, unless X-GE-STATUS-SEVERITY maps the alert's status to another severity.

What happens to fields Oppex does not recognise?

Oppex keeps them in the incident's details, so responders can see them on the incident.