Webhooks
Receive real-time notifications when events occur in your account.
Overview
Webhooks allow you to receive HTTP POST requests when specific events occur, such as when a job completes or fails. This is more efficient than polling for status updates.
Configure webhooks from your Dashboard or include a webhook URL in your API requests.
Events
| Event | Description |
|---|---|
| job.started | A job has started processing |
| job.completed | A job has completed successfully |
| job.failed | A job has failed |
| job.progress | Progress update during processing |
Webhook Payload
When an event occurs, we send a POST request to your webhook URL with a JSON payload:
{
"event": "job.completed",
"timestamp": "2026-01-11T10:30:02Z",
"data": {
"request_id": "req_abc123xyz",
"status": "completed",
"model": "fal-ai/flux/schnell",
"output": {
"items": [
{
"type": "image",
"url": "https://cdn.abstrakt.one/outputs/abc123.png",
"width": 1024,
"height": 1024
}
]
},
"metrics": {
"inference_time": 1.823,
"queue_time": 0.045
}
}
}Signature Verification
All webhook requests include a signature header that you should verify to ensure the request came from Abstrakt.
Security Warning
Always verify webhook signatures in production to prevent spoofed requests.
Headers
| Header | Description |
|---|---|
| X-Abstrakt-Signature | HMAC-SHA256 signature of the payload |
| X-Abstrakt-Timestamp | Unix timestamp of when the request was sent |
Verification Example (Node.js)
import crypto from 'crypto';
function verifyWebhookSignature(payload, signature, timestamp, secret) {
const signedPayload = `${timestamp}.${JSON.stringify(payload)}`;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// In your webhook handler:
app.post('/webhooks/abstrakt', (req, res) => {
const signature = req.headers['x-abstrakt-signature'];
const timestamp = req.headers['x-abstrakt-timestamp'];
if (!verifyWebhookSignature(req.body, signature, timestamp, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process the webhook...
res.status(200).send('OK');
});Best Practices
- •Return quickly: Respond with 2xx within 30 seconds. Process asynchronously if needed.
- •Handle retries: We retry failed deliveries up to 3 times with exponential backoff.
- •Idempotency: Use the request_id to handle duplicate deliveries.
- •HTTPS only: Webhook URLs must use HTTPS in production.
Testing Webhooks
Use the "Test" button in your Webhook settings to send a sample payload to your endpoint.
For local development, use a tool like ngrok to expose your local server to the internet.