Backup EnginebackupEngine
Docs/API Reference/Webhooks

Webhooks

Receive real-time notifications for backup events, billing changes, and security alerts.

Webhook Overview

BackupEngine can send HTTP POST requests to your endpoints when specific events occur. This enables real-time integration with monitoring systems, ticketing tools, chat applications, and custom dashboards without polling the API.

  • Configure webhook endpoints in the Customer Portal under Settings → Webhooks.
  • Each webhook can subscribe to specific event types or receive all events.
  • Webhooks include a cryptographic signature for verification.
  • Failed deliveries are retried with exponential backoff for up to 24 hours.

Event Types

BackupEngine emits the following event types. Subscribe to the categories relevant to your integration.

  • backup.started — A backup run has begun.
  • backup.completed — A backup run completed successfully.
  • backup.failed — A backup run failed with an error.
  • backup.warning — A backup completed with warnings (e.g., some files skipped).
  • restore.started — A restore operation has begun.
  • restore.completed — A restore operation completed successfully.
  • device.registered — A new device was registered to the account.
  • device.offline — A device has not connected for the configured threshold period.
  • security.ransomware_detected — Suspicious file activity matching ransomware patterns was detected.
  • security.mfa_disabled — MFA was disabled on a team member's account (should not happen but is monitored).
  • billing.payment_failed — A subscription payment failed.
  • billing.plan_changed — The subscription plan was upgraded or downgraded.
  • billing.approaching_limit — Storage usage is approaching the plan limit (80% threshold).

Webhook Payload

All webhook payloads follow a consistent JSON structure with event metadata and event-specific data.

Example webhook payload
POST https://your-endpoint.com/webhooks/backupengine
Content-Type: application/json
X-BackupEngine-Signature: sha256=a1b2c3d4e5f6...
X-BackupEngine-Event: backup.completed
X-BackupEngine-Delivery: dlv_abc123

{
  "event": "backup.completed",
  "timestamp": "2025-12-15T02:15:12Z",
  "delivery_id": "dlv_abc123",
  "account_id": "acct_abc123",
  "data": {
    "backup_id": "bak_run_abc123",
    "device_id": "dev_abc123",
    "device_name": "Work Laptop",
    "backup_set": "Documents",
    "status": "completed",
    "start_time": "2025-12-15T02:00:00Z",
    "end_time": "2025-12-15T02:15:12Z",
    "files_processed": 3847,
    "bytes_uploaded": 1288490188,
    "dedup_savings_percent": 88.5
  }
}

Signature Verification

Every webhook request includes a cryptographic signature in the X-BackupEngine-Signature header. Always verify this signature before processing the webhook to ensure the request is authentic.

Signature verification (Node.js)
import crypto from 'crypto';

function verifyWebhookSignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf-8')
    .digest('hex');

  const received = signature.replace('sha256=', '');

  return crypto.timingSafeEqual(
    Buffer.from(expected, 'hex'),
    Buffer.from(received, 'hex')
  );
}

// Express.js handler
app.post('/webhooks/backupengine', (req, res) => {
  const signature = req.headers['x-backupengine-signature'] as string;
  const isValid = verifyWebhookSignature(
    JSON.stringify(req.body),
    signature,
    process.env.BACKUPENGINE_WEBHOOK_SECRET!
  );

  if (!isValid) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const event = req.body;
  switch (event.event) {
    case 'backup.failed':
      // Send alert to Slack, PagerDuty, etc.
      break;
    case 'security.ransomware_detected':
      // Trigger incident response
      break;
  }

  res.status(200).json({ received: true });
});

⚠ Warning

Always use constant-time comparison (timingSafeEqual) when verifying signatures to prevent timing attacks. Never use simple string equality (===) for signature comparison.

💡 Tip

Store your webhook signing secret in an environment variable, not in your codebase. The secret is displayed once when you create the webhook endpoint in the Customer Portal.