Docs/API/Webhooks

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

EventDescription
job.startedA job has started processing
job.completedA job has completed successfully
job.failedA job has failed
job.progressProgress 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

HeaderDescription
X-Abstrakt-SignatureHMAC-SHA256 signature of the payload
X-Abstrakt-TimestampUnix 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.