Skip to content

Webhook API

1. Purpose

This document describes the common webhook delivery protocol.

It covers:

  • HTTP request format.
  • HMAC signature verification.
  • Receiver response rules.
  • Retry behavior.
  • Idempotency requirements.

2. Endpoint

Webhook requests are sent to the customer-provided HTTP or HTTPS endpoint configured in webhook_config.url.

Request method:

text
POST

Content type:

text
application/json

HTTP and HTTPS endpoints are both supported. HTTPS is recommended for production environments.

3. Headers

Each request contains the following headers:

text
Content-Type: application/json
X-Webhook-Event-Id: alarm:123456
X-Webhook-Event-Type: business_alarm.created
X-Webhook-Timestamp: 1782017700
X-Webhook-Signature-Version: v1
X-Webhook-Signature: sha256=<signature>

Header descriptions:

HeaderDescription
Content-TypeAlways application/json.
X-Webhook-Event-IdUnique event ID. Receivers should use it as the idempotency key.
X-Webhook-Event-TypeTop-level event type, such as hardware_alarm.created or business_alarm.created.
X-Webhook-TimestampUnix timestamp in seconds when the request was signed.
X-Webhook-Signature-VersionSignature version. Current value is v1.
X-Webhook-SignatureHMAC-SHA256 signature in sha256=<hex> format.

4. Signature

The signature verifies that the webhook request was sent by the system and that the body was not modified in transit.

Signature payload:

text
timestamp + "." + eventId + "." + rawBody

Algorithm:

text
HMAC-SHA256(secret, signaturePayload)

The result is sent as:

text
sha256=<hex-encoded-signature>

Recommended receiver behavior:

  1. Read X-Webhook-Timestamp.
  2. Rebuild the signature payload using the timestamp, event ID, and raw request body.
  3. Calculate HMAC-SHA256 using the shared secret.
  4. Compare the calculated signature with X-Webhook-Signature.
  5. Deduplicate requests using eventId.

X-Webhook-Timestamp primarily participates in the HMAC signature payload and helps ensure signature consistency and request integrity. The current protocol does not require receivers to reject requests based on a fixed timestamp tolerance window.

Receivers that need replay protection may apply their own timestamp tolerance rule, such as +/-5 minutes or a wider window, according to their security policy.

Important note:

text
Signature verification must use the raw request body exactly as received.

The webhook secret is a shared secret agreed upon during webhook configuration. In the current version, the secret is not expected to change frequently unless there is a specific security requirement. If the secret needs to be changed, the integration parties should complete the change through a mutually confirmed configuration update process.

5. Receiver Response

The receiver does not need to return a specific JSON body.

Any HTTP status code in the following range is treated as successful delivery:

text
200 <= statusCode < 300

Recommended successful response:

http
HTTP/1.1 200 OK
Content-Type: application/json

{
  "received": true
}

The response body is optional. The system only uses the HTTP status code to decide whether delivery succeeded.

The following responses are treated as delivery failures:

text
3xx redirection
4xx client error
5xx server error
request timeout
network error
connection refused
TLS or HTTP client error

If the receiver returns 409 Conflict, 422 Unprocessable Entity, or another non-2xx status for a duplicate event, the system still treats it as a failure and may retry it.

For duplicate events, the receiver should return a 2xx response after deduplication.

6. Retry Policy

Webhook delivery is asynchronous. Alarm processing is not blocked by webhook delivery.

When an event is ready to be sent, it is written to the webhook outbox first. A scheduled delivery task reads pending outbox records and sends HTTP POST requests to the configured endpoint.

Events are generally processed according to their creation and persistence order, but receivers should not rely on a strict global delivery order. Different event types may be generated through different paths, and scheduling delays, network delays, and retry logic may affect the arrival order.

For the same device and the same type of event, under normal conditions where the receiver returns a 2xx response, the system tries to deliver events in their creation order. If an earlier event enters the retry flow, a later event may arrive before the retried event. Receivers that need business ordering should use the event occurrence time or trigger time in the payload, such as occurredAt, and may also use eventSequence as a stable alarm-event sequence number, instead of relying only on webhook arrival time.

Default delivery timeout:

text
timeoutMs = 10000

The timeout can be configured per webhook configuration.

Default maximum failed attempts:

text
maxRetry = 5

This means the system may try to deliver the same event up to five failed delivery attempts in total. After the final failed attempt, the outbox record is marked as failed and no further automatic retry is scheduled.

Retry delay schedule:

Failed attemptNext retry delay
160 seconds
2300 seconds
3900 seconds
43600 seconds
5 and later21600 seconds

With the default maxRetry = 5, the fifth failure marks the event as failed, so the fifth delay is only used if a larger maxRetry is configured.

Duplicate delivery is mainly possible while an event is still within its retry lifecycle. With the default retry policy, this is usually approximately 1-2 hours after the first failed attempt.

If the receiver successfully processes an event but the HTTP response is lost, times out, or cannot be confirmed by the system, the same event may still be delivered again. Receivers should maintain idempotency records for eventId for a reasonable period, such as 24 hours or longer, depending on their storage and processing strategy.

7. Delivery Status

Delivery status values:

StatusMeaning
PENDINGThe event is waiting for first delivery.
RETRYThe last delivery failed and the event is waiting for the next retry time.
SUCCESSThe receiver returned a 2xx HTTP status code.
FAILEDDelivery is no longer retryable, or the webhook configuration is disabled or invalid.

Only a simple delivery log is printed by the system. No separate historical delivery table is required in the first version.

8. Receiver Requirements

Receivers should follow these rules:

  1. Use eventId as the idempotency key.
  2. Return a 2xx response for duplicate events that were already processed successfully.
  3. Process the raw request body before modifying it if signature verification is required.
  4. Keep the endpoint fast and stable.
  5. Handle long-running business processing asynchronously on the receiver side.
  6. Avoid returning non-2xx status codes for business-level validation failures after the event has already been accepted.