Webhooks API¶
Real-time event notifications for document processing and workflow events.
Overview¶
Webhooks allow you to receive HTTP callbacks when events occur in Archivus.
Common Use Cases:
- Document processing completion notifications
- Workflow status updates
- Integration with external systems
- Automated downstream processing
Create Webhook¶
Create a new webhook endpoint.
Request Body¶
{
"url": "https://yourapp.com/webhooks/archivus",
"events": [
"document.processed",
"document.failed",
"chat.message.created",
"dag.execution.completed"
],
"secret": "your-webhook-secret"
}
Example Request¶
const response = await fetch('https://api.archivus.app/api/v1/webhooks', {
method: 'POST',
headers: {
'X-API-Key': 'ak_live_YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://yourapp.com/webhooks/archivus',
events: ['document.processed', 'document.failed'],
secret: 'your-webhook-secret'
})
});
Response¶
{
"id": "webhook_abc123",
"url": "https://yourapp.com/webhooks/archivus",
"events": ["document.processed", "document.failed"],
"status": "active",
"created_at": "2026-01-18T10:30:00Z"
}
Webhook Events¶
Available Events¶
| Event | Description |
|---|---|
document.processed | Document processing completed successfully |
document.failed | Document processing failed |
document.uploaded | New document uploaded |
chat.message.created | New chat message created |
chat.session.created | New chat session created |
dag.execution.started | Workflow execution started |
dag.execution.completed | Workflow execution completed |
dag.execution.failed | Workflow execution failed |
dag.task.created | Human task created |
dag.task.completed | Human task completed |
Event Payload¶
All webhook events follow this structure:
{
"id": "event_abc123",
"type": "document.processed",
"timestamp": "2026-01-18T10:30:00Z",
"data": {
"document_id": "doc_abc123",
"status": "completed",
"ai_summary": "Contract analysis completed",
"ai_tags": ["contract", "legal"]
}
}
Webhook Verification¶
Signature Header¶
Archivus includes a signature in the X-Archivus-Signature header:
Verification Example¶
import hmac
import hashlib
def verify_webhook(payload, signature, secret):
expected_signature = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(
f"sha256={expected_signature}",
signature
)
# Usage
payload = request.data
signature = request.headers.get('X-Archivus-Signature')
secret = 'your-webhook-secret'
if verify_webhook(payload, signature, secret):
# Process webhook
event = json.loads(payload)
handle_event(event)
else:
return 'Invalid signature', 401
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(`sha256=${expectedSignature}`),
Buffer.from(signature)
);
}
// Usage
const payload = JSON.stringify(req.body);
const signature = req.headers['x-archivus-signature'];
const secret = 'your-webhook-secret';
if (verifyWebhook(payload, signature, secret)) {
// Process webhook
handleEvent(req.body);
} else {
res.status(401).send('Invalid signature');
}
Webhook Handler Example¶
Node.js Express¶
const express = require('express');
const crypto = require('crypto');
const app = express();
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;
app.post('/webhooks/archivus',
express.raw({ type: 'application/json' }),
(req, res) => {
const signature = req.headers['x-archivus-signature'];
const payload = req.body.toString();
// Verify signature
const expectedSignature = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(payload)
.digest('hex');
if (signature !== `sha256=${expectedSignature}`) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process event
const event = JSON.parse(payload);
switch (event.type) {
case 'document.processed':
handleDocumentProcessed(event.data);
break;
case 'document.failed':
handleDocumentFailed(event.data);
break;
case 'dag.execution.completed':
handleWorkflowCompleted(event.data);
break;
}
res.json({ status: 'ok' });
}
);
Python Flask¶
from flask import Flask, request, jsonify
import hmac
import hashlib
app = Flask(__name__)
WEBHOOK_SECRET = os.environ['WEBHOOK_SECRET']
@app.route('/webhooks/archivus', methods=['POST'])
def archivus_webhook():
signature = request.headers.get('X-Archivus-Signature')
payload = request.get_data(as_text=True)
# Verify signature
expected = hmac.new(
WEBHOOK_SECRET.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(f"sha256={expected}", signature):
return jsonify({"error": "Invalid signature"}), 401
# Process event
event = request.json
if event['type'] == 'document.processed':
handle_document_processed(event['data'])
elif event['type'] == 'document.failed':
handle_document_failed(event['data'])
elif event['type'] == 'dag.execution.completed':
handle_workflow_completed(event['data'])
return jsonify({"status": "ok"}), 200
Best Practices¶
Security¶
Always Verify Signatures
Never process webhooks without verifying the signature. This prevents unauthorized requests.
- Use HTTPS - Webhook URLs must use HTTPS
- Verify signatures - Always verify the
X-Archivus-Signatureheader - Rotate secrets - Regularly rotate webhook secrets
- Validate events - Verify event types before processing
Reliability¶
- Return 200 quickly - Respond within 5 seconds
- Process asynchronously - Queue webhook events for background processing
- Handle duplicates - Implement idempotency using event IDs
- Log all events - Log webhooks for debugging and monitoring
Error Handling¶
- Retry logic - Archivus will retry failed webhooks (exponential backoff)
- Monitor failures - Track webhook delivery failures
- Fallback mechanisms - Have backup methods to poll for status
Manage Webhooks¶
List Webhooks¶
Update Webhook¶
Delete Webhook¶
Testing¶
Test Webhook Locally¶
Use tools like ngrok or localtunnel to expose your local server:
# Using ngrok
ngrok http 3000
# Update webhook URL to ngrok URL
curl -X PUT https://api.archivus.app/api/v1/webhooks/webhook_abc123 \
-H "X-API-Key: ak_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://abc123.ngrok.io/webhooks/archivus"
}'
Next Steps¶
-
Upload Documents
Trigger webhook events with document uploads
-
Workflow Events
Monitor workflow execution via webhooks