About Webhooks

Webhooks allow you to receive real-time notifications when events occur in your Level organization. When an event happens, Level will send an HTTP POST request to your configured endpoint with details about the event.

Setting Up Webhooks

Creating a Webhook

  1. Navigate to Settings → Webhooks in your Level dashboard
  2. Click Create webhook
  3. Configure your webhook:
    • URL: Your endpoint that will receive webhook requests
    • Secret: A secret key used to validate webhook authenticity (recommended)
    • Event types: Select which events you want to receive
    • Status: Enable/disable the webhook

Managing Webhooks

  • View webhook request logs and responses in real-time
  • Retry failed webhook deliveries
  • Monitor webhook performance and success rates

Event Types

Level supports the following webhook events:

Event TypeDescription
alert_activeTriggered when an alert becomes active
alert_resolvedTriggered when an alert is resolved
device_createdTriggered when a new device is added
device_updatedTriggered when a device is modified
device_deletedTriggered when a device is removed
group_createdTriggered when a new group is created
group_updatedTriggered when a group is modified
group_deletedTriggered when a group is removed

Webhook Payload Structure

All webhook payloads follow this consistent structure:

{
  "event_type": "device_created",
  "event_id": "550e8400-e29b-41d4-a716-446655440000",
  "occurred_at": "2025-03-15T14:30:00.000Z",
  "data": {
    "id": "123456789",
    // and other properties
  }
}

Payload Fields

  • event_type: The type of event that occurred
  • event_id: Unique identifier for this webhook delivery
  • occurred_at: ISO 8601 timestamp when the event occurred
  • data: Event-specific data containing the affected resource

Securing Webhooks

Level signs webhook payloads using HMAC SHA256 to ensure authenticity.

Signature Verification

Each webhook request includes an X-Level-Signature header:

X-Level-Signature: sha256=a1b2c3d4e5f6...

To verify the signature:

Node.js Example

const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');
  
  const receivedSignature = signature.replace('sha256=', '');
  
  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature, 'hex'),
    Buffer.from(receivedSignature, 'hex')
  );
}

Python Example

import hmac
import hashlib

def verify_webhook(payload, signature, secret):
    expected_signature = hmac.new(
        secret.encode('utf-8'),
        payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    
    received_signature = signature.replace('sha256=', '')
    
    return hmac.compare_digest(expected_signature, received_signature)

Ruby Example

require 'openssl'

def verify_webhook(payload, signature, secret)
  expected_signature = OpenSSL::HMAC.hexdigest('SHA256', secret, payload)
  received_signature = signature.gsub('sha256=', '')
  
  Rack::Utils.secure_compare(expected_signature, received_signature)
end

Handling Webhook Deliveries

Best Practices

  1. Respond quickly: Return a 2xx status code within 10 seconds
  2. Process asynchronously: Queue webhook processing for complex operations
  3. Validate signatures: Always verify webhook authenticity using the secret
  4. Handle duplicates: Use the event_id to prevent processing duplicate events
  5. Implement idempotency: Ensure your webhook handler can safely process the same event multiple times

Delivery and Retries

  • Level delivers webhooks asynchronously using background jobs
  • Failed deliveries are automatically retried up to 3 times
  • Retry attempts use exponential backoff with jitter (2+ minutes between attempts)
  • Only HTTP 2xx responses are considered successful

Example Handler (Express.js)

const express = require('express');
const app = express();

app.use(express.raw({ type: 'application/json' }));

app.post('/webhooks/level', (req, res) => {
  const signature = req.headers['x-level-signature'];
  const payload = req.body.toString();
  
  // Verify signature
  if (!verifyWebhook(payload, signature, process.env.LEVEL_WEBHOOK_SECRET)) {
    return res.status(401).send('Unauthorized');
  }
  
  const event = JSON.parse(payload);
  
  // Process event asynchronously
  processWebhookEvent(event);
  
  // Respond immediately
  res.status(200).send('OK');
});

async function processWebhookEvent(event) {
  switch (event.event_type) {
    case 'alert_active':
      await handleAlertActive(event.data);
      break;
    case 'device_created':
      await handleDeviceCreated(event.data);
      break;
    // Handle other event types...
  }
}

Troubleshooting

Viewing Request Logs

Access detailed webhook request logs in Settings → Webhooks → [Your Webhook]:

  • Request and response bodies
  • HTTP status codes
  • Error messages
  • Delivery timestamps

Common Issues

  • 404/500 errors: Check your endpoint URL and server status
  • Timeout errors: Ensure your handler responds within 10 seconds
  • Signature validation fails: Verify your secret matches the webhook configuration
  • Missing events: Check that the event type is selected in your webhook configuration

Testing Webhooks

  1. Use webhook testing tools like ngrok for local development
  2. Check webhook logs for delivery details and responses
  3. Use the "Re-run request" feature to replay failed deliveries
  4. Monitor webhook success rates in the dashboard

For additional support, contact our developer support team.