Incident Webhook Push¶
Webhooks 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 create tickets, sync status, or trigger automation workflows based on the received data.
You can create and manage webhooks at Incident Center > Configuration Management > Webhook.
Prerequisites¶
Prepare a third-party address that can receive POST requests. Webhooks support HTTP and HTTPS addresses; HTTPS is recommended for production environments. For security reasons, private network, loopback, or localhost addresses cannot be configured.
Configure a Webhook¶
- On the Webhook page, click Create Webhook;
- Enter a name and the third-party receiving URL;
- Select the incident events to automatically 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 applies to incidents generated by incident aggregation rules. |
- Click Generate Token. The token is generated only by the Guance platform; copy it immediately and save it securely in the third-party receiving service's key configuration;
- Set the enabled status and save.
You can skip selecting auto-trigger events. After a webhook is enabled, even if no auto-trigger events are configured, you can still manually send from the incident detail page.
Note
- The token is the authentication key for the webhook. After generation, the platform shows the plaintext only once; subsequent pages display only a masked value. Regenerating the token immediately invalidates the old one.
- Webhook delivery failures do not affect incident creation, update, recovery, or closure.
- Webhooks use a fixed request method, authentication method, and timeout; no additional configuration is needed.
Test Send¶
After saving a webhook, click Test in the actions for that webhook and select an event type. The system sends a test data payload in the standard 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 are not counted in formal send statistics.
Manual Send¶
On the incident detail page, click Send Webhook to immediately send the latest snapshot of the incident to an enabled webhook. Select a webhook, enter a description (1–1000 characters), and send. Manual send has the following characteristics:
- Supports all incident states, unaffected by the webhook's auto-trigger event configuration or aggregation window.
- Only one webhook can be selected per send; the same member cannot submit duplicate requests for the same incident and webhook within 5 seconds.
- A
2xxstatus code is considered success; network errors, invalid URLs, response timeouts, or non-2xxstatus codes are considered failures. - The send result is recorded in Send History with the event type displayed as "Manual Triggered" and the send type still "Formal".
- Failed sends are not automatically retried. To resend, return to the incident detail page and trigger again.
The payload of a manual send follows the request protocol and incident snapshot structure, with the following additional information:
| Field | Description |
|---|---|
eventTypes |
Contains incident.manual_triggered. |
triggerSource |
Fixed to manual. |
manualContext |
Manual send context, including the operator, send description, and operation time. |
Manual sends do not add records to the incident collaboration log or activity timeline.
Request Protocol¶
The system sends JSON data via POST with a request timeout of 5 seconds and does not follow redirects. The receiving service returns any 2xx status code to indicate successful delivery.
Request Headers¶
| Header | Description |
|---|---|
Content-Type |
Fixed to application/json. |
Authorization |
Fixed format: Bearer <Token>. |
X-Incidents-Event-Id |
Unique identifier for this delivery, can be used for idempotency on the receiving end. |
X-Incidents-Timestamp |
Unix timestamp in seconds. |
X-Incidents-Signature |
HMAC-SHA256 signature, format: 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 of a webhook delivery batch, not the original event ID. |
eventTypes |
Incident change types included in this batch. |
eventTime |
Unix timestamp in seconds of this delivery. |
workspaceUUID |
UUID of the workspace the incident belongs to. |
incident |
Complete current snapshot of the incident; see below for fields. resourceContent is not pushed. |
isTest |
Whether this is a test send. |
incident Field Description¶
incident is the incident snapshot at the time of sending. It is 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 the incident in the third-party system. |
workspaceUUID |
string | UUID of the workspace the incident belongs to. |
name |
string | Incident title. |
level |
string | Current incident level UUID or level identifier. |
description |
string | Incident description. |
incidentsStatus |
string | Incident business status. Common values: open (unassigned), working (in progress), resolved (resolved), closed (closed). |
assigner |
array | List of UUIDs of current assignee accounts; 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 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. For incidents generated by aggregation rules, this is fixed to incident_aggregation. |
resourceUUID |
string | Source resource UUID. |
resourceUrl |
string | Access URL of the source resource; empty if no URL exists. |
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 | Snapshot of the aggregation rule name recorded at 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 may expand as product capabilities evolve; third parties should ignore unrecognized fields. |
status |
integer | Incident record status, used to indicate whether the record is valid; do not use this as the incident business status. |
creator |
string | UUID of the account or system identifier that created the incident record. |
updator |
string | UUID of the account or system identifier that last updated the incident record. |
createAt |
integer | Incident record creation time, Unix timestamp in seconds. |
updateAt |
integer | Incident record last update time, Unix timestamp in seconds. |
deleteAt |
integer | Incident record deletion time; usually a negative value if not deleted. |
Each entry in eventRelations represents a currently associated event. Fields that are always 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 | Snapshot of aggregation key-value pairs. Keys are the full field paths saved in the rule, values are the normalized values used to generate the aggregation identity. Only returned for associated events of aggregated incidents. |
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 this gracefully. Changes to the associated event snapshot or aggregation key-values of an aggregated incident trigger the "Aggregation Changed" event.
Verify Request Origin¶
The third-party receiving service should verify the token, timestamp, and signature simultaneously.
The signature message is:
Where rawRequestBody is the raw request bytes received; do not format or re-serialize the JSON first. It is recommended to only accept requests within 5 minutes of 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 occur for the same incident within a short period for the same webhook, the system merges them into a single delivery and returns the included change types in the eventTypes of the payload. The payload always reflects the latest incident snapshot at the time of sending.
The system does not automatically retry. You can view delivery results in Send History by send status, incident UUID, or event type. Failed records display the response code and error details to help troubleshoot the third-party receiving service. If an automatic push fails, you can go to the corresponding incident detail page and trigger a manual send to resend.