Level webhooks send alert, device, and group events to an HTTP endpoint that you control. Use them when your integration needs event-driven updates instead of polling the Public API.
This article covers the request format and receiver behavior. To create a webhook, choose events, manage the secret, and review delivery logs in Level, see Webhook Settings.
For per-event payload schemas, see the Level Developer Documentation.
ℹ️ NOTE: These are outbound event webhooks. To start a Level automation from an inbound request, see Webhook Trigger.
Before you begin
You need:
Admin access to configure the webhook in Level.
A publicly reachable HTTPS endpoint.
A high-entropy secret shared between Level and your receiver.
A way to store processed event IDs or make event handling idempotent.
Configure the destination and event selection under Settings → Webhooks by following Webhook Settings.
Request format
Level sends an HTTP POST with:
Content-Type: application/json
When the webhook has a secret, Level also sends:
X-Level-Signature: sha256=
Every event uses this JSON envelope:
{
"event_type": "device_created",
"event_id": "550e8400-e29b-41d4-a716-446655440000",
"occurred_at": "2026-03-13T18:30:00.000Z",
"data": {
"id": "..."
}
}
Field | Type | Description |
| string | Identifies the type of event. |
| UUID | Identifies the event and stays the same when the payload is delivered again. |
| ISO 8601 datetime in UTC | Time the event was generated. |
| object | Resource-specific event data. |
Use the webhook payload reference for the schema of each data object.
Event types
| When it is sent |
| A new alert is raised. |
| An existing alert is resolved. |
| A device is added. |
| Device data or configuration changes. |
| A device is removed. |
| A device group is created. |
| A group's name or configuration changes. |
| A group is deleted. |
The event types delivered to one endpoint depend on the selection saved in Settings → Webhooks.
Verify the signature
When a secret is configured, Level computes HMAC-SHA256 over the exact JSON request body.
Verify the request before parsing or processing the body:
Read the raw request body as bytes.
Compute HMAC-SHA256 over those exact bytes, using the webhook secret as the key.
Encode the digest as lowercase hexadecimal.
Prefix the digest with
sha256=.Compare it with
X-Level-Signatureusing a constant-time comparison.Reject the request if the values do not match.
⚠️ WARNING: Parsing and re-serializing the JSON before computing the HMAC can change whitespace or field formatting and produce a different digest. Verify the raw request body.
The signature header is omitted if the webhook has no secret. Configure a secret for production destinations.
Process events safely
A receiver should:
Accept requests only over HTTPS.
Verify
X-Level-Signaturebefore trusting the payload.Validate
event_type,event_id,occurred_at, and the expecteddataschema.Record
event_idor use an idempotent operation.Place longer work on your own queue.
Return a successful
2xxresponse after accepting the event.
Failed requests may be retried automatically, and an administrator can manually re-run a delivery from Level. Either path can send the same event_id more than once.
💡 TIP: Use event_id as an idempotency key. If your receiver has already processed it, return success without repeating the operation.
Troubleshoot delivery
Use Settings → Webhooks → Requests to review recorded attempts. The request details can include:
Delivery status.
HTTP response status.
Destination URL.
Event time.
Connection or HTTP error.
Response body.
After fixing the destination, use Re-run request to resend the stored payload. A re-run uses the same event ID, so the receiver must handle it as a possible duplicate.
See Webhook Settings for the full configuration and delivery-log workflow.
