Incident Webhook Push¶
Webhook is used to push key changes of incidents to third-party systems. You can integrate incident information into ITSM, automation platforms, or internal business systems, allowing third parties to continue creating tickets, synchronizing statuses, or triggering automated processes based on the received data.
Webhooks can be created and managed in Incident Center > Configuration Management > Webhook.
Prerequisites¶
First, prepare a third-party address that can receive POST requests. Webhook supports HTTP and HTTPS addresses; HTTPS is recommended for production environments. For security reasons, intranet, loopback, or local addresses cannot be configured.
Configure Webhook¶
- Click Create Webhook on the Webhook page;
- Fill in the name and third-party receiving URL;
- Select the incident events to push: | Event | Description | | --- | --- | | Incident Created | Pushed when a new incident is created. | | Status Changed | Pushed when the incident status changes. | | Level Changed | Pushed when the incident level changes. | | Assignee Changed | Pushed when the incident assignee changes. | | Aggregation Changed | Pushed when the aggregated incident's associated events change. Only effective for incidents generated by incident aggregation rules. |
- Click Generate Token. The Token is only generated by the Guance platform. Copy it immediately and securely save it in the key configuration of the third-party receiving service;
- Set the enabled status and save.
Note
- Token is the authentication key for Webhook. After generation, the platform only displays the plaintext once; subsequent pages will only show the masked value. Regenerating the Token will immediately invalidate the old Token;
- Failure to deliver Webhook will not affect the creation, update, recovery, or closure of incidents;
- Webhook uses a fixed request method, authentication method, and timeout period, no additional configuration is required.
Test Send¶
After saving the Webhook, click Test in the Webhook's operations and select the event type. The system will send a test data in the formal request format, with isTest set to true in the Payload.
Test results can be viewed in Send History. Test sends do not affect real incidents and will not be counted in the formal send statistics.
Request Protocol¶
The system sends JSON data via POST with a request timeout of 5 seconds and does not follow redirects. The receiving service returning any 2xx status code is considered a successful delivery.
Request Header¶
| Header | Description |
|---|---|
Content-Type |
Fixed as application/json. |
Authorization |
Fixed format as Bearer <Token>. |
X-Incidents-Event-Id |
Unique identifier for this delivery, can be used for idempotent processing on the receiving end. |
X-Incidents-Timestamp |
Unix timestamp in seconds. |
X-Incidents-Signature |
HMAC-SHA256 signature, format as v1=<signature>. |
Payload Example¶
{
"eventId": "evt_01JXYZ...",
"eventTypes": [
"incident.created",
"incident.status_changed"
],
"eventTime": 1783000000,
"workspaceUUID": "wksp_xxx",
"incident": {
"uuid": "incident_xxx",
"name": "API service unavailable",
"level": "level_1",
"incidentsStatus": "working",
"resourceType": "incident_aggregation",
"aggregationRuleUUID": "rule_xxx",
"aggregationRuleNameSnapshot": "生产环境服务聚合",
"eventRelations": [
{
"df_fault_id": "fault_xxx",
"status": "critical",
"aggregationValues": {
"df_workspace_name": "production",
"df_dimension_tags.host": "web-01"
}
}
]
},
"isTest": false
}
Field descriptions:
| Field | Description |
|---|---|
eventId |
Unique ID for a Webhook delivery batch, not the original event ID. |
eventTypes |
Types of incident changes included in this batch. |
eventTime |
Unix timestamp in seconds for this delivery. |
workspaceUUID |
UUID of the workspace to which the incident belongs. |
incident |
Current full snapshot of the incident, see below for field details. resourceContent will not be pushed. |
isTest |
Whether it is a test send. |
incident Field Descriptions¶
incident is the incident snapshot at the time of sending. It will be updated as the incident's level, status, assignee, and associated events change.
| Field | Type | Description |
|---|---|---|
id |
integer | Internal numeric ID of the incident record. |
uuid |
string | Incident UUID, format incident_xxx, recommended as the primary key for third-party incidents. |
workspaceUUID |
string | UUID of the workspace to which the incident belongs. |
name |
string | Incident title. |
level |
string | Current incident level UUID or level identifier. |
description |
string | Incident description. |
incidentsStatus |
string | Incident business status. Common values include open (pending assignment), working (in progress), resolved (resolved), and closed (closed). |
assigner |
array | List of account UUIDs of current assignees; empty array if unassigned. |
statusTime |
object | Timestamp records for each incident business status. |
statusChangeTime |
integer | Unix timestamp in seconds of the last incident business status change. |
cumulativeTime |
integer | Cumulative duration of the incident, in seconds. |
eventCount |
integer | Total number of events currently associated with the incident. |
eventUpdateAt |
integer | Unix timestamp in seconds of the last associated event update. |
eventRelations |
array | Snapshot of currently associated events, see below for field descriptions. |
source |
string | Incident source identifier. |
resourceCategory |
string | Source resource category. |
resourceType |
string | Source resource type. Incidents generated by aggregation rules are fixed as incident_aggregation. |
resourceUUID |
string | Source resource UUID. |
resourceUrl |
string | Access URL of the source resource; empty if no address. |
resourceIdentity |
string | Resource identifier used to identify the same source incident. |
aggregationRuleUUID |
string | UUID of the rule that generated the aggregated incident. Only returned for aggregated incidents. |
aggregationRuleNameSnapshot |
string | Name snapshot of the aggregation rule recorded at the time of incident creation. Only returned for aggregated incidents; can be used to identify historical sources after the rule is renamed or deleted. |
dimensionTag |
object | Dimension tags associated with the incident. |
dtHost |
string | Extracted host dimension value. |
dtService |
string | Extracted service dimension value. |
dtResource |
string | Extracted resource dimension value. |
dtPodName |
string | Extracted Pod name dimension value. |
dtAppName |
string | Extracted application name dimension value. |
dtAppId |
string | Extracted application ID dimension value. |
dtEnv |
string | Extracted environment dimension value. |
dtUrl |
string | Extracted URL dimension value. |
extend |
object | Incident extension information. This object will evolve with product capabilities; third parties should ignore unrecognized fields. |
status |
integer | Incident record status, used to identify whether the record is valid; do not use it as the incident business status. |
creator |
string | Account UUID or system identifier that created the incident record. |
updator |
string | Account UUID or system identifier that last updated the incident record. |
createAt |
integer | Creation time of the incident record, Unix timestamp in seconds. |
updateAt |
integer | Last update time of the incident record, Unix timestamp in seconds. |
deleteAt |
integer | Deletion time of the incident record, usually a negative value if not deleted. |
Each item in eventRelations represents a currently associated event. Fields that are stably returned include:
| Field | Type | Description |
|---|---|---|
df_fault_id |
string | Fault ID of the associated event. |
status |
string | Current status of the associated event, e.g., critical or ok. |
aggregationValues |
object | Aggregation key-value snapshot. Keys are the full field paths saved by the rule, values are the standardized values used when generating the aggregation identity; only returned for aggregated incident associated events. |
Different event sources may carry additional fields. Third parties should identify associated events by df_fault_id and ignore unrecognized extension fields. For historical aggregated incidents, aggregationValues may be missing or empty; the receiving end should handle it compatibly. When the associated event snapshot or aggregation key-value of an aggregated incident changes, the "Aggregation Changed" event will be triggered.
Verify Request Source¶
The third-party receiving service should verify the Token, timestamp, and signature simultaneously.
The original text for signature is:
Where rawRequestBody is the original request bytes received; do not format or re-serialize JSON first. It is recommended to only accept requests within 5 minutes before and after the current time, and deduplicate by eventId.
import hashlib
import hmac
import time
def verify_webhook(request, token):
raw_body = request.get_data(cache=True)
timestamp = request.headers.get("X-Incidents-Timestamp", "")
event_id = request.headers.get("X-Incidents-Event-Id", "")
signature = request.headers.get("X-Incidents-Signature", "")
authorization = request.headers.get("Authorization", "")
if not hmac.compare_digest(authorization, f"Bearer {token}"):
return False
if not timestamp.isdigit() or abs(time.time() - int(timestamp)) > 300:
return False
message = f"{timestamp}.{event_id}.".encode("utf-8") + raw_body
expected = "v1=" + hmac.new(
token.encode("utf-8"), message, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
boolean verify(byte[] rawBody, String timestamp, String eventId,
String signature, String authorization, String token) throws Exception {
if (!MessageDigest.isEqual(
authorization.getBytes(StandardCharsets.UTF_8),
("Bearer " + token).getBytes(StandardCharsets.UTF_8))) return false;
byte[] prefix = (timestamp + "." + eventId + ".").getBytes(StandardCharsets.UTF_8);
byte[] content = new byte[prefix.length + rawBody.length];
System.arraycopy(prefix, 0, content, 0, prefix.length);
System.arraycopy(rawBody, 0, content, prefix.length, rawBody.length);
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(token.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
String expected = "v1=" + java.util.HexFormat.of().formatHex(mac.doFinal(content));
return MessageDigest.isEqual(expected.getBytes(StandardCharsets.UTF_8),
signature.getBytes(StandardCharsets.UTF_8));
}
import (
"crypto/hmac"
"crypto/sha256"
"fmt"
)
func verifyWebhook(rawBody []byte, timestamp, eventID, signature, authorization, token string) bool {
if !hmac.Equal([]byte(authorization), []byte("Bearer "+token)) {
return false
}
content := append([]byte(timestamp+"."+eventID+"."), rawBody...)
mac := hmac.New(sha256.New, []byte(token))
mac.Write(content)
expected := fmt.Sprintf("v1=%x", mac.Sum(nil))
return hmac.Equal([]byte(expected), []byte(signature))
}
Delivery and Send History¶
When multiple changes to the same incident occur within a short period for the same Webhook, the system will merge them into one delivery and return the types of changes included in this batch in the eventTypes of the Payload. The Payload always uses the latest incident snapshot at the time of sending.
The system does not automatically retry, nor does it support manual retry. You can view delivery results in Send History by send status, incident UUID, or event type; failed records will show response codes and error details for troubleshooting the third-party receiving service.