Webhook Notifications
You can receive automatic webhook notifications when PDF generation is complete. This eliminates the need for polling and enables real-time detection of completion, allowing you to automate workflows such as email sending.
Overview
Webhook notifications are automatically sent for all PDF generation endpoints:
POST /file/sync/single- Synchronous single file generationPOST /file/sync/multiple- Synchronous multiple file generationPOST /file/async/single- Asynchronous single file generationPOST /file/async/multiple- Asynchronous multiple file generation
Setting Up Webhook URL
To configure the Webhook URL, use the ReportFlow workspace settings screen:
- Open workspace settings
- Navigate to the "Developer" tab
- Enter the HTTPS URL to receive notifications in the "Webhook URL" field
- Click "Update"
Webhook Notification Payload
When PDF generation is complete, the following payload is POSTed to the configured Webhook URL.
Payload Format
{
"event": "file.completed",
"timestamp": "2026-02-15T10:30:45.123Z",
"workspaceId": "ws_abc123",
"designId": "design_123",
"version": 5,
"files": [
{
"fileId": "file_xyz",
"uuid": "uuid_456",
"fileName": "invoice.pdf",
"params": {
"companyName": "Company A",
"amount": 50000
}
}
]
}
Field Descriptions
| Field | Type | Description |
|---|---|---|
event | string | Fixed value: "file.completed" |
timestamp | string | Event occurrence time (ISO 8601 format) |
workspaceId | string | Workspace ID |
designId | string | Design ID |
version | number | Version number |
files | array | Array of generated file information |
files[].fileId | string | File ID (unique identifier) |
files[].uuid | string | UUID for downloading |
files[].fileName | string | File name (with extension) |
files[].params | object | Parameters used during generation |
Downloading PDFs
From the webhook notification payload, you can download PDFs using the following information:
workspaceId: From payload'sworkspaceIddesignId: From payload'sdesignIduuid: From payload'sfiles[].uuid
See File Download for details.
Implementation Examples
Node.js (Express)
const express = require('express');
const axios = require('axios');
const app = express();
app.use(express.json());
app.post('/webhooks/pdf-completed', async (req, res) => {
const payload = req.body;
// Event verification
if (payload.event !== 'file.completed') {
return res.status(400).json({ error: 'Unknown event' });
}
console.log(`PDF generation completed: ${payload.files.length} files`);
// Download each file
for (const file of payload.files) {
const downloadUrl = `https://${payload.workspaceId}.re-port-flow.com/v1/file/download/${file.uuid}/${file.fileId}`;
try {
// Download PDF
const pdfResponse = await axios.get(downloadUrl, {
headers: {
'AppKey': process.env.APP_KEY,
'SecretKey': process.env.SECRET_KEY
},
responseType: 'arraybuffer'
});
const pdfBuffer = Buffer.from(pdfResponse.data);
// Send email, etc.
await sendEmailWithAttachment({
to: extractEmailFromParams(file.params),
subject: `PDF File: ${file.fileName}`,
attachments: [{
filename: file.fileName,
content: pdfBuffer
}]
});
console.log(`Email sent: ${file.fileName}`);
} catch (error) {
console.error(`File download error: ${file.fileName}`, error.message);
}
}
// Return 200 OK
res.status(200).json({ received: true });
});
app.listen(3000, () => {
console.log('Webhook server listening on port 3000');
});
Python (Flask)
from flask import Flask, request, jsonify
import requests
import os
app = Flask(__name__)
@app.route('/webhooks/pdf-completed', methods=['POST'])
def webhook_handler():
payload = request.json
# Event verification
if payload.get('event') != 'file.completed':
return jsonify({'error': 'Unknown event'}), 400
workspace_id = payload['workspaceId']
print(f"PDF generation completed: {len(payload['files'])} files")
# Download each file
for file_info in payload['files']:
download_url = f"https://{workspace_id}.re-port-flow.com/v1/file/download/{file_info['uuid']}/{file_info['fileId']}"
try:
# Download PDF
pdf_response = requests.get(
download_url,
headers={
'AppKey': os.getenv('APP_KEY'),
'SecretKey': os.getenv('SECRET_KEY')
}
)
pdf_response.raise_for_status()
# Save to file
with open(file_info['fileName'], 'wb') as f:
f.write(pdf_response.content)
print(f"Download completed: {file_info['fileName']}")
except Exception as e:
print(f"Error: {file_info['fileName']}, {str(e)}")
# Return 200 OK
return jsonify({'received': True}), 200
if __name__ == '__main__':
app.run(port=3000)
Security Best Practices
1. Use HTTPS URLs
Webhook URLs must use HTTPS. HTTP URLs are rejected.
2. Implement Signature Verification
Currently, webhook notifications do not include payload signatures. To prevent spoofing, we recommend verifying the source using the following methods:
- IP whitelist
- Authentication with API Key or secret token
- Custom signature scheme
3. Timeout Configuration
Webhook endpoints should respond within 5 seconds. For heavy processing (email sending, database writes, etc.), use asynchronous job queues.
4. Do Not Include Credentials in URL
Do not include authentication tokens or secrets in Webhook URL query parameters. If authentication is required, send it via Header or manage it separately.
Retry Behavior
ReportFlow automatically retries when your webhook endpoint returns the following status codes:
- 200-299: Success (no retry)
- 400-499: Client error (no retry)
- 500-599: Server error (retry)
Retries are performed up to 3 times. Even if all retries fail, the PDF generation process itself is considered successful.
Troubleshooting
Notifications Not Received
Check the following:
-
Is the Webhook URL configured?
- Check in Workspace Settings > Developer tab
-
Using HTTPS?
- HTTP URLs are rejected
-
Using a public URL?
localhostand private IP addresses are rejected- For testing, use services like webhook.site
-
Does the endpoint return 200?
- If returning error status codes (4xx/5xx), retries will occur
- Check your endpoint logs
If notifications still don't arrive, please contact support.
Next Steps
- Async Workflows - Bulk generation workflows using webhook notifications
- Error Handling - How to handle errors
- File Download - How to download PDF files