Webhook Events
conversion.completed
Fired when a document conversion successfully completes
Example Payload:
{
"id": "conv_abc123",
"status": "completed",
"created_at": "2024-01-23T10:30:00Z",
"completed_at": "2024-01-23T10:30:05Z",
"input_file": "document.pdf",
"output_url": "https://cdn.flexidoc.io/outputs/abc123.html",
"metadata": {}
}
conversion.failed
Fired when a document conversion fails
Example Payload:
{
"id": "conv_abc123",
"status": "failed",
"error": {
"code": "invalid_document",
"message": "The PDF file is corrupted or invalid"
}
}
batch.progress
Fired periodically during batch processing with progress updates
Example Payload:
{
"batch_id": "batch_xyz789",
"total": 100,
"completed": 45,
"failed": 2,
"percentage": 47
}
batch.completed
Fired when all conversions in a batch are complete
Example Payload:
{
"batch_id": "batch_xyz789",
"total": 100,
"successful": 98,
"failed": 2,
"duration_seconds": 145
}
Quick Start Implementation
Step 1: Configure Your Webhook Endpoint
curl -X POST https://api.flexidoc.io/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.example.com/webhook/flexidoc",
"events": [
"conversion.completed",
"conversion.failed",
"batch.completed"
],
"description": "Production webhook endpoint"
}'
Use the API to register your webhook endpoint. You can specify which events you want to receive.
Step 2: Implement Your Webhook Handler
import express from 'express';
import crypto from 'crypto';
const app = express();
app.use(express.json());
// Webhook endpoint
app.post('/webhook/flexidoc', (req, res) => {
// Verify webhook signature
const signature = req.headers['x-flexidoc-signature'];
const timestamp = req.headers['x-flexidoc-timestamp'];
const payload = JSON.stringify(req.body);
const expectedSignature = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(`${timestamp}.${payload}`)
.digest('hex');
if (signature !== expectedSignature) {
return res.status(401).send('Invalid signature');
}
// Process webhook event
const { event, data } = req.body;
switch (event) {
case 'conversion.completed':
console.log('Conversion completed:', data.id);
// Handle successful conversion
break;
case 'conversion.failed':
console.error('Conversion failed:', data.error);
// Handle failed conversion
break;
}
// Always respond quickly
res.status(200).send('OK');
});
Webhook Security
Important Security Notice
Always verify webhook signatures to ensure requests are from FlexiDoc. Never process webhooks without signature verification in production environments.
Signature Verification
Each webhook request includes a signature in the X-FlexiDoc-Signature
header.
The signature is computed using HMAC-SHA256 with your webhook secret and the request timestamp + body.
Timestamp Validation
Check the X-FlexiDoc-Timestamp
header to prevent replay attacks.
Reject requests older than 5 minutes to ensure webhook freshness.
Webhook Best Practices
Respond Quickly
Return a 2xx status code within 5 seconds. Process webhooks asynchronously.
Verify Signatures
Always validate webhook signatures to ensure requests come from FlexiDoc.
Handle Retries
Implement idempotency to handle potential duplicate webhook deliveries.
Use HTTPS
Webhook endpoints must use HTTPS with valid SSL certificates.
Webhook Delivery & Retries
Automatic Retry Policy
FlexiDoc automatically retries failed webhook deliveries with exponential backoff.
Note: After 5 failed attempts, the webhook is marked as failed. You can manually replay failed webhooks from your dashboard.