Skip to main content

Webhooks API

The Webhooks API allows you to receive real-time HTTP notifications when events occur in FireBackup. Configure webhook endpoints to integrate with external systems, trigger workflows, or send alerts.

Endpoints Overview

MethodEndpointDescription
GET/webhooksList all webhooks
GET/webhooks/:idGet webhook details
POST/webhooksCreate webhook
PUT/webhooks/:idUpdate webhook
DELETE/webhooks/:idDelete webhook
PATCH/webhooks/:id/toggleEnable/disable webhook
POST/webhooks/:id/testTest webhook delivery

List Webhooks

Get all webhooks for the organization.

GET /api/v1/webhooks
Authorization: Bearer YOUR_TOKEN
X-Organization-Id: YOUR_ORG_ID

Response:

{
"success": true,
"data": [
{
"id": "webhook_abc123",
"name": "Slack Backup Notifications",
"url": "https://hooks.slack.com/services/xxx/yyy/zzz",
"events": ["backup.completed", "backup.failed"],
"enabled": true,
"lastTriggeredAt": "2024-01-15T10:00:45Z",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-15T10:00:45Z"
},
{
"id": "webhook_def456",
"name": "PagerDuty Alerts",
"url": "https://events.pagerduty.com/v2/enqueue",
"events": ["backup.failed", "restore.failed"],
"enabled": true,
"lastTriggeredAt": null,
"createdAt": "2024-01-10T00:00:00Z",
"updatedAt": "2024-01-10T00:00:00Z"
}
]
}

Get Webhook

Get details of a specific webhook.

GET /api/v1/webhooks/:id
Authorization: Bearer YOUR_TOKEN
X-Organization-Id: YOUR_ORG_ID

Response:

{
"success": true,
"data": {
"id": "webhook_abc123",
"name": "Slack Backup Notifications",
"url": "https://hooks.slack.com/services/xxx/yyy/zzz",
"events": ["backup.completed", "backup.failed"],
"secret": "••••••••",
"enabled": true,
"lastTriggeredAt": "2024-01-15T10:00:45Z",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-15T10:00:45Z"
}
}

Create Webhook

Create a new webhook endpoint.

POST /api/v1/webhooks
Authorization: Bearer YOUR_TOKEN
X-Organization-Id: YOUR_ORG_ID
Content-Type: application/json

{
"name": "Slack Backup Notifications",
"url": "https://hooks.slack.com/services/xxx/yyy/zzz",
"events": ["backup.completed", "backup.failed"],
"secret": "my-webhook-secret",
"enabled": true
}

Request Body:

FieldTypeRequiredDefaultDescription
namestringYes-Webhook display name
urlstringYes-Endpoint URL to receive notifications
eventsarrayYes-Events to subscribe to
secretstringNo-Secret for HMAC signature verification
enabledbooleanNotrueEnable webhook

Response:

{
"success": true,
"data": {
"id": "webhook_xyz789",
"name": "Slack Backup Notifications",
"url": "https://hooks.slack.com/services/xxx/yyy/zzz",
"events": ["backup.completed", "backup.failed"],
"enabled": true,
"createdAt": "2024-01-15T11:00:00Z"
}
}

Update Webhook

Update webhook settings.

PUT /api/v1/webhooks/:id
Authorization: Bearer YOUR_TOKEN
X-Organization-Id: YOUR_ORG_ID
Content-Type: application/json

{
"name": "Slack Notifications (Updated)",
"events": ["backup.completed", "backup.failed", "restore.completed"]
}

Request Body:

All fields are optional. Only provided fields are updated.

FieldTypeDescription
namestringWebhook display name
urlstringEndpoint URL
eventsarrayEvents to subscribe to
secretstringSecret for HMAC verification
enabledbooleanEnable/disable webhook

Response:

{
"success": true,
"data": {
"id": "webhook_abc123",
"name": "Slack Notifications (Updated)",
"events": ["backup.completed", "backup.failed", "restore.completed"],
"updatedAt": "2024-01-15T12:00:00Z"
}
}

Delete Webhook

Delete a webhook.

DELETE /api/v1/webhooks/:id
Authorization: Bearer YOUR_TOKEN
X-Organization-Id: YOUR_ORG_ID

Response:

{
"success": true,
"message": "Webhook deleted successfully"
}

Toggle Webhook

Enable or disable a webhook.

PATCH /api/v1/webhooks/:id/toggle
Authorization: Bearer YOUR_TOKEN
X-Organization-Id: YOUR_ORG_ID
Content-Type: application/json

{
"enabled": false
}

Request Body:

FieldTypeRequiredDescription
enabledbooleanYesEnable or disable webhook

Response:

{
"success": true,
"data": {
"id": "webhook_abc123",
"enabled": false,
"updatedAt": "2024-01-15T12:00:00Z"
}
}

Test Webhook

Send a test payload to verify webhook configuration.

POST /api/v1/webhooks/:id/test
Authorization: Bearer YOUR_TOKEN
X-Organization-Id: YOUR_ORG_ID

Response:

{
"success": true,
"data": {
"webhookId": "webhook_abc123",
"webhookName": "Slack Backup Notifications",
"event": "backup.completed",
"url": "https://hooks.slack.com/services/xxx/yyy/zzz",
"success": true,
"statusCode": 200,
"duration": 245
}
}

Test Failure Response

{
"success": true,
"data": {
"webhookId": "webhook_abc123",
"webhookName": "Slack Backup Notifications",
"event": "backup.completed",
"url": "https://hooks.slack.com/services/xxx/yyy/zzz",
"success": false,
"statusCode": 404,
"error": "Request failed with status code 404",
"duration": 150
}
}

Webhook Events

Backup Events

EventDescription
backup.startedBackup job started
backup.completedBackup completed successfully
backup.failedBackup failed

Restore Events

EventDescription
restore.startedRestore job started
restore.completedRestore completed successfully
restore.failedRestore failed

Schedule Events

EventDescription
schedule.createdSchedule was created
schedule.updatedSchedule was updated
schedule.deletedSchedule was deleted

Webhook Payload Format

All webhook deliveries use the following payload format:

{
"event": "backup.completed",
"timestamp": "2024-01-15T10:00:45Z",
"data": {
// Event-specific data
}
}

Backup Events Payload

{
"event": "backup.completed",
"timestamp": "2024-01-15T10:00:45Z",
"data": {
"backupId": "bkp_abc123",
"projectId": "proj_xyz789",
"projectName": "Production App",
"type": "full",
"status": "completed",
"documentsCount": 15000,
"collectionsCount": 12,
"originalSize": 45000000,
"compressedSize": 6200000,
"duration": 45,
"triggeredBy": "schedule",
"scheduleId": "sched_abc123",
"createdAt": "2024-01-15T10:00:00Z",
"completedAt": "2024-01-15T10:00:45Z"
}
}

Backup Failed Payload

{
"event": "backup.failed",
"timestamp": "2024-01-15T10:00:45Z",
"data": {
"backupId": "bkp_abc123",
"projectId": "proj_xyz789",
"projectName": "Production App",
"type": "full",
"status": "failed",
"error": "Failed to connect to Firebase: Token expired",
"triggeredBy": "schedule",
"scheduleId": "sched_abc123",
"createdAt": "2024-01-15T10:00:00Z",
"failedAt": "2024-01-15T10:00:15Z"
}
}

Restore Events Payload

{
"event": "restore.completed",
"timestamp": "2024-01-15T11:02:30Z",
"data": {
"restoreJobId": "restore_abc123",
"backupId": "bkp_xyz789",
"projectId": "proj_abc123",
"projectName": "Production App",
"targetProjectId": "proj_def456",
"targetProjectName": "Staging App",
"status": "completed",
"documentsRestored": 10000,
"collectionsRestored": 5,
"mergeMode": "overwrite",
"duration": 150,
"createdAt": "2024-01-15T11:00:00Z",
"completedAt": "2024-01-15T11:02:30Z"
}
}

Schedule Events Payload

{
"event": "schedule.created",
"timestamp": "2024-01-15T11:00:00Z",
"data": {
"scheduleId": "sched_abc123",
"name": "Daily Production Backup",
"projectId": "proj_xyz789",
"projectName": "Production App",
"cronExpression": "0 2 * * *",
"timezone": "America/New_York",
"enabled": true,
"nextRunAt": "2024-01-16T07:00:00Z",
"createdBy": {
"id": "user_abc123",
"email": "admin@example.com"
}
}
}

Webhook Headers

Each webhook request includes the following headers:

HeaderDescription
Content-Typeapplication/json
X-Webhook-EventEvent type (e.g., backup.completed)
X-Webhook-TimestampISO 8601 timestamp
X-Webhook-IdWebhook configuration ID
X-Webhook-SignatureHMAC-SHA256 signature (if secret configured)

Signature Verification

When a secret is configured, FireBackup includes an HMAC-SHA256 signature to verify authenticity.

Signature Format

X-Webhook-Signature: sha256=abc123def456...

Verification Example (Node.js)

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = 'sha256=' +
crypto.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');

return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}

// Express middleware example
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const isValid = verifyWebhookSignature(req.body, signature, 'your-secret');

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

// Process webhook
console.log('Received event:', req.body.event);
res.status(200).json({ received: true });
});

Verification Example (Python)

import hmac
import hashlib
import json

def verify_webhook_signature(payload, signature, secret):
expected_signature = 'sha256=' + hmac.new(
secret.encode(),
json.dumps(payload).encode(),
hashlib.sha256
).hexdigest()

return hmac.compare_digest(signature, expected_signature)

# Flask example
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-Webhook-Signature')
is_valid = verify_webhook_signature(
request.json,
signature,
'your-secret'
)

if not is_valid:
return {'error': 'Invalid signature'}, 401

# Process webhook
print(f"Received event: {request.json['event']}")
return {'received': True}, 200

Delivery Behavior

Timeouts

Webhook requests have a 30-second timeout. Ensure your endpoint responds quickly.

Retry Policy

Currently, FireBackup does not retry failed webhook deliveries. Implement your own reliability by:

  1. Responding quickly (under 30 seconds)
  2. Processing webhooks asynchronously
  3. Returning 2xx status codes for successful receipt

Response Expectations

Response CodeInterpretation
2xxSuccessful delivery
3xxRedirect (not followed)
4xxClient error (delivery failed)
5xxServer error (delivery failed)

Integration Examples

Slack Integration

{
"name": "Slack Notifications",
"url": "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX",
"events": ["backup.completed", "backup.failed"]
}

You'll need a middleware to transform FireBackup payloads to Slack format.

Discord Integration

{
"name": "Discord Alerts",
"url": "https://discord.com/api/webhooks/000000000000000000/xxxx",
"events": ["backup.failed", "restore.failed"]
}

PagerDuty Integration

{
"name": "PagerDuty Incidents",
"url": "https://events.pagerduty.com/v2/enqueue",
"events": ["backup.failed"]
}

Custom Endpoint

{
"name": "Custom Backend",
"url": "https://api.yourcompany.com/firebackup-webhooks",
"events": ["backup.started", "backup.completed", "backup.failed"],
"secret": "your-secret-key-here"
}

Best Practices

Security

  1. Always use HTTPS - Never use HTTP URLs in production
  2. Configure secrets - Enable HMAC verification for all webhooks
  3. Validate signatures - Verify every incoming webhook
  4. Use short-lived tokens - If forwarding to other services

Performance

  1. Respond quickly - Return 200 immediately, process async
  2. Handle duplicates - Implement idempotency
  3. Monitor failures - Track webhook delivery status

Reliability

  1. Log payloads - Store received webhooks for debugging
  2. Queue processing - Use message queues for complex workflows
  3. Alert on failures - Monitor your webhook endpoints

Webhook Object

FieldTypeDescription
idstringUnique webhook ID
namestringDisplay name
urlstringEndpoint URL
eventsarraySubscribed events
secretstringHMAC secret (masked)
enabledbooleanWhether webhook is active
lastTriggeredAtstringLast delivery timestamp
createdAtstringISO 8601 timestamp
updatedAtstringISO 8601 timestamp

Error Responses

Webhook Not Found

{
"success": false,
"error": {
"code": "WEBHOOK_NOT_FOUND",
"message": "Webhook not found"
}
}

Invalid URL

{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid URL format",
"details": {
"field": "url",
"reason": "Must be a valid HTTPS URL"
}
}
}

Invalid Events

{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid event type",
"details": {
"field": "events",
"invalidValues": ["invalid.event"],
"allowedValues": [
"backup.started",
"backup.completed",
"backup.failed",
"restore.started",
"restore.completed",
"restore.failed",
"schedule.created",
"schedule.updated",
"schedule.deleted"
]
}
}
}

Delivery Failed

{
"success": true,
"data": {
"webhookId": "webhook_abc123",
"success": false,
"error": "Connection timed out",
"duration": 30000
}
}