Webhooks & Events
API version: v1 Estimated reading time: 12 minutes Audience: Integrators and backend developers
Booga Enterprise has a built-in event system that publishes notifications when significant actions occur across the platform. You can subscribe to these events and receive real-time webhook deliveries at your own HTTP endpoints, enabling event-driven integrations without polling.
How Webhooks Work
The webhook flow has four stages:
- An event occurs — a user uploads a file, an agent completes a workflow, a chat message is sent, etc.
- The platform publishes an event — the event is recorded with its type, payload, and metadata
- Matching subscriptions are evaluated — the platform checks which webhook subscriptions match the event type
- Webhook deliveries are dispatched — the event payload is sent as an HTTP POST to each matching subscription's URL, signed with HMAC-SHA256
If delivery fails, the platform retries with exponential backoff until the delivery succeeds or the maximum retry count is reached.
Creating a Webhook Subscription
Webhook subscriptions are managed via the API or through the Booga Enterprise dashboard.
Via the API
curl -X POST \
-H "Authorization: Bearer $BOOGA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "File Upload Notifications",
"subscription_type": "webhook",
"event_types": ["file.uploaded", "file.processed"],
"webhook_url": "https://your-server.com/webhooks/booga",
"is_active": true
}' \
https://api.boogaenterprise.com/api/webhooks/
The response includes a webhook_secret that you will use to verify delivery signatures. Store this secret securely.
Via the Dashboard
- Navigate to the Admin Portal → Events section
- Click Create Subscription
- Select Webhook as the subscription type
- Choose the event types you want to receive
- Enter your webhook endpoint URL
- Save — the webhook secret is displayed for you to copy
Webhook Delivery Format
Each webhook delivery is an HTTP POST request to your endpoint with a JSON body and authentication headers.
Headers
| Header | Description |
|---|---|
Content-Type | application/json |
X-Booga-Event | The event type (e.g., file.uploaded) |
X-Booga-Tenant | The tenant ID that generated the event |
X-Booga-Event-Id | Unique identifier for this event (UUID) |
X-Booga-Signature | HMAC-SHA256 signature for payload verification (sha256=<hex_digest>) |
Payload Structure
{
"event_id": "e7a2c8d1-3f4b-5c6d-7e8f-9a0b1c2d3e4f",
"event_type": "file.uploaded",
"tenant_id": "t1a2b3c4-d5e6-f7g8-h9i0-j1k2l3m4n5o6",
"timestamp": "2026-03-30T14:30:00Z",
"data": {
"file_id": "f8c1d2e3-4a5b-6c7d-8e9f-0a1b2c3d4e5f",
"name": "Q4-Report.pdf",
"size": 1048576,
"content_type": "application/pdf",
"uploaded_by": "user@example.com"
}
}
The data field contains event-specific details. Its structure varies by event type — see Event Types below.
Verifying Webhook Signatures
Every webhook delivery includes an X-Booga-Signature header containing an HMAC-SHA256 signature computed over the raw request body using your webhook secret. Always verify this signature to ensure the delivery is authentic and has not been tampered with.
Verification Steps
- Read the raw request body (before JSON parsing)
- Compute HMAC-SHA256 of the body using your webhook secret
- Compare the computed signature with the value in
X-Booga-Signature
Python Example
import hmac
import hashlib
def verify_webhook(request_body: bytes, signature_header: str, secret: str) -> bool:
"""Verify the HMAC-SHA256 signature of a webhook delivery."""
expected = hmac.new(
secret.encode('utf-8'),
request_body,
hashlib.sha256
).hexdigest()
received = signature_header.replace('sha256=', '')
return hmac.compare_digest(expected, received)
# In your webhook handler:
raw_body = request.body # raw bytes, not parsed JSON
signature = request.headers.get('X-Booga-Signature', '')
webhook_secret = 'your_webhook_secret_here'
if not verify_webhook(raw_body, signature, webhook_secret):
return HttpResponse(status=401) # reject unsigned/tampered deliveries
# Signature valid — process the event
event = json.loads(raw_body)
Node.js Example
const crypto = require('crypto');
function verifyWebhook(rawBody, signatureHeader, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
const received = signatureHeader.replace('sha256=', '');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(received)
);
}
// In your Express handler:
app.post('/webhooks/booga', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-booga-signature'] || '';
if (!verifyWebhook(req.body, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
console.log(`Received event: ${event.event_type}`);
res.status(200).send('OK');
});
Important: Use constant-time comparison (
hmac.compare_digestin Python,crypto.timingSafeEqualin Node.js) to prevent timing attacks.
Retry Logic
When a webhook delivery fails (non-2xx response or network error), the platform retries automatically with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | ~2 minutes |
| 2nd retry | ~4 minutes |
| 3rd retry | ~8 minutes |
| 4th retry | ~16 minutes |
| 5th retry | ~30 minutes (capped) |
The delay formula is base_delay × 2^(attempt - 1), capped at 30 minutes. Each delivery attempt is recorded with its status, response code, and timestamp.
Your Endpoint's Responsibilities
To ensure reliable delivery:
- Return a 2xx status code (200, 201, 202, 204) promptly to acknowledge receipt
- Respond within 30 seconds — requests that time out are treated as failures and retried
- Process events asynchronously — accept the webhook, return 200 immediately, and process the payload in a background job to avoid timeouts
- Handle duplicates — in rare cases (network interruptions, retries), you may receive the same event more than once. Use the
X-Booga-Event-Idheader to deduplicate
Event Types
The platform publishes events across all major feature areas. Common event types include:
Files
| Event Type | Trigger |
|---|---|
file.uploaded | A file is uploaded to the platform |
file.processed | File processing (text extraction, embedding) completes |
file.deleted | A file is deleted |
file.shared | A file is shared with other users or organisations |
Chat
| Event Type | Trigger |
|---|---|
chat.session.created | A new chat session is started |
chat.message.sent | A message is sent in a chat session |
chat.session.ended | A chat session is closed |
Agents
| Event Type | Trigger |
|---|---|
agent.execution.started | An agent workflow begins execution |
agent.execution.completed | An agent workflow completes successfully |
agent.execution.failed | An agent workflow fails |
Knowledge
| Event Type | Trigger |
|---|---|
knowledge.item.created | A new item is added to the knowledge base |
knowledge.item.updated | A knowledge base item is updated |
knowledge.embedding.completed | Embedding generation for a knowledge item finishes |
Users & Organizations
| Event Type | Trigger |
|---|---|
user.created | A new user is added to the tenant |
user.updated | User profile or permissions are changed |
organization.created | A new organisation is created |
organization.member.added | A user is added to an organisation |
System
| Event Type | Trigger |
|---|---|
webhook.test | A test delivery is triggered from the dashboard |
webhook.subscription.created | A new webhook subscription is created |
The full list of event types is available via the event registry in the Admin Portal Events section, or by calling GET /api/webhooks/event-types/.
Webhook Templates
Webhook templates transform event payloads into formats expected by specific receiving systems. The platform includes built-in templates for popular services:
| Template | Output Format |
|---|---|
| Default | Standard JSON payload passthrough |
| Slack | Slack Block Kit message format |
| Teams | Microsoft Teams Adaptive Card format |
| Discord | Discord embed message format |
| Custom | User-defined transformation logic |
Templates are applied per subscription. When a template is configured, the raw event payload is transformed before delivery. Configure templates in the API Management → Webhook Management section of the dashboard.
Testing a Template
Before applying a template to a live subscription, test it with sample data:
curl -X POST \
-H "Authorization: Bearer $BOOGA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_id": "<template_id>",
"sample_data": {
"event_type": "file.uploaded",
"data": {"file_id": "test-123", "name": "report.pdf"}
}
}' \
https://api.boogaenterprise.com/api/webhook-templates/test/
Managing Subscriptions
List Subscriptions
curl -s -H "Authorization: Bearer $BOOGA_API_KEY" \
https://api.boogaenterprise.com/api/webhooks/
Update a Subscription
curl -X PATCH \
-H "Authorization: Bearer $BOOGA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"event_types": ["file.uploaded", "file.processed", "file.deleted"]}' \
https://api.boogaenterprise.com/api/webhooks/<subscription_id>/
Test Delivery
Send a test event to verify your endpoint is reachable:
curl -X POST \
-H "Authorization: Bearer $BOOGA_API_KEY" \
https://api.boogaenterprise.com/api/webhooks/<subscription_id>/test/
Regenerate Webhook Secret
If your webhook secret is compromised, regenerate it:
curl -X POST \
-H "Authorization: Bearer $BOOGA_API_KEY" \
https://api.boogaenterprise.com/api/webhooks/<subscription_id>/regenerate_secret/
Update your endpoint's verification logic with the new secret immediately — deliveries signed with the old secret will fail verification.
View Delivery History
curl -s -H "Authorization: Bearer $BOOGA_API_KEY" \
"https://api.boogaenterprise.com/api/webhooks/<subscription_id>/deliveries/?limit=20"
Each delivery record includes the event type, HTTP status code, response body, attempt count, and timestamps.
Retry Failed Deliveries
Manually retry all failed deliveries for a subscription:
curl -X POST \
-H "Authorization: Bearer $BOOGA_API_KEY" \
https://api.boogaenterprise.com/api/webhooks/<subscription_id>/retry_failed_deliveries/
Best Practices
- Always verify signatures — reject any delivery that fails HMAC-SHA256 verification to prevent spoofed events
- Respond quickly, process later — return 200 immediately and process the payload asynchronously to avoid timeouts and retries
- Implement idempotency — use
X-Booga-Event-Idto detect and skip duplicate deliveries caused by retries - Monitor delivery health — check the delivery history periodically for persistent failures that may indicate endpoint issues
- Use HTTPS endpoints — webhook URLs should always use HTTPS to protect payload data in transit
- Scope subscriptions narrowly — subscribe only to the event types your integration needs to reduce unnecessary traffic
- Handle secret rotation gracefully — when regenerating a webhook secret, update your verification code first, then regenerate; during the transition, accept deliveries signed with either secret
- Log webhook payloads — retain received payloads for debugging, especially during initial integration development
Troubleshooting
Not receiving webhook deliveries
Verify that your subscription is active (is_active: true) and that the webhook URL is correct and publicly reachable. Use the test delivery endpoint to confirm connectivity. Check the delivery history for error details — common issues include DNS resolution failures, TLS certificate errors, and firewall rules blocking inbound POST requests.
Signature verification fails
Ensure you are computing the HMAC over the raw request body bytes (not the parsed JSON object). Verify that your secret matches the one from the subscription. If you recently regenerated the secret, update your verification code with the new value.
Receiving duplicate events
Duplicates can occur when your endpoint takes too long to respond (causing a retry) or during network interruptions. Implement idempotency by tracking processed X-Booga-Event-Id values and skipping events you have already handled.
Deliveries show repeated failures
Check the delivery log response bodies for error details from your server. Common causes include application errors (500), authentication requirements on your endpoint (401/403), or payload size issues. Ensure your endpoint can handle POST requests with JSON bodies up to several kilobytes.
Related Topics
- Integration Getting Started — build your first API integration
- Authentication & Authorization — API key scopes and security
- Architecture Overview — how the event system fits into the platform
- API Management — User Guide — webhook templates and delivery monitoring in the dashboard
- Integrations — User Guide — inbound webhooks from external systems
- API Reference — interactive OpenAPI documentation
Related Topics
⏱️ Read time: 12 minutes | 📊 Difficulty: intermediate