Webhooks

Receive real-time notifications when events occur in Fairu

Introduction

Webhooks allow Fairu to send real-time HTTP notifications to your systems when events occur. Instead of polling the API for changes, webhooks push data to your endpoint as soon as something happens—whether a file is uploaded, a license expires, or a workflow completes.

Common use cases

  • Sync with external systems – Automatically update your CMS, PIM, or DAM when files change
  • Trigger workflows – Start automated processes when specific events occur
  • Send notifications – Alert your team via Slack, email, or other channels
  • Audit logging – Track all changes to your digital assets in an external system

Quick start

  1. Navigate to Settings → Webhooks in your Fairu dashboard
  2. Click Create webhook
  3. Enter your endpoint URL (must be HTTPS in production)
  4. Select the events you want to receive
  5. Configure authentication (optional but recommended)
  6. Save and activate your webhook

Configuration options

When creating or editing a webhook, you can configure the following:

FieldDescription
NameA descriptive name to identify this webhook
URLThe endpoint that will receive webhook requests (HTTPS recommended)
AuthenticationOptional authentication method (None, Basic, or Bearer)
SubscriptionsThe entity types and events you want to receive
ActiveToggle to enable or disable the webhook

Events reference

Fairu supports webhooks for six entity types, each with its own set of events.

File events

EventDescription
file.createdA new file was uploaded
file.updatedA file's metadata was modified
file.deletedA file was deleted
file.signedA document was signed
file.duplicatedA file was duplicated
file.movedA file was moved to a different folder
file.downloadedA file was downloaded
file.copyright_assignedA copyright was assigned to a file
file.license_assignedA license was assigned to a file

Folder events

EventDescription
folder.createdA new folder was created
folder.updatedA folder's metadata was modified
folder.deletedA folder was deleted
folder.movedA folder was moved to a different location
EventDescription
copyright.createdA new copyright was created
copyright.updatedA copyright was modified
copyright.deletedA copyright was deleted
copyright.assignedA copyright was assigned to one or more files

License events

EventDescription
license.createdA new license was created
license.updatedA license was modified
license.deletedA license was deleted
license.expiredA license has expired
license.assignedA license was assigned to one or more files
EventDescription
gallery.createdA new gallery was created
gallery.updatedA gallery was modified
gallery.deletedA gallery was deleted
gallery.sharedA gallery was shared
gallery.images_addedImages were added to a gallery
gallery.images_removedImages were removed from a gallery

Workflow events

EventDescription
workflow.createdA new workflow was created
workflow.updatedA workflow was modified
workflow.deletedA workflow was deleted
workflow.triggeredA workflow was triggered
workflow.completedA workflow completed execution

Payload structure

Each webhook request is sent as an HTTP POST with a JSON body. Multiple events may be batched into a single request.

{
  "webhook_id": "550e8400-e29b-41d4-a716-446655440000",
  "events": [
    {
      "type": "file.created",
      "entity_type": "file",
      "entity_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "event_type": "created",
      "timestamp": "2026-02-03T12:00:00+00:00",
      "payload": {
        "entity_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
      }
    }
  ],
  "sent_at": "2026-02-03T12:00:05+00:00"
}

Field descriptions

FieldTypeDescription
webhook_idstring (UUID)The ID of the webhook configuration
eventsarrayArray of event objects
events[].typestringCombined event type (e.g., file.created)
events[].entity_typestringThe entity type (file, folder, copyright, license, gallery, workflow)
events[].entity_idstring (UUID)The ID of the affected entity
events[].event_typestringThe event that occurred (e.g., created, updated)
events[].timestampstring (ISO 8601)When the event occurred
events[].payloadobjectAdditional event-specific data
sent_atstring (ISO 8601)When the webhook request was sent

Authentication

Fairu supports three authentication methods to secure your webhook endpoint.

None

No authentication is applied. The request is sent without any Authorization header. Only use this for testing or internal endpoints.

Basic authentication

HTTP Basic Auth sends credentials in the Authorization header.

Setup: Enter your credentials in the format username:password

The request will include:

Authorization: Basic base64(username:password)

Bearer token

A bearer token is sent in the Authorization header.

Setup: Enter your token value (without the "Bearer" prefix)

The request will include:

Authorization: Bearer your-token-here

Receiving webhooks

Here's an example of how to receive and process webhooks in Node.js with Express:

const express = require('express');
const app = express();
 
app.use(express.json());
 
app.post('/webhooks/fairu', (req, res) => {
  const { webhook_id, events, sent_at } = req.body;
 
  // Process each event
  for (const event of events) {
    console.log(`Received ${event.type} for ${event.entity_id}`);
 
    switch (event.entity_type) {
      case 'file':
        handleFileEvent(event);
        break;
      case 'folder':
        handleFolderEvent(event);
        break;
      case 'license':
        handleLicenseEvent(event);
        break;
      // ... handle other entity types
    }
  }
 
  // Respond quickly with 200 OK
  res.status(200).send('OK');
});
 
function handleFileEvent(event) {
  switch (event.event_type) {
    case 'created':
      console.log(`New file created: ${event.entity_id}`);
      break;
    case 'updated':
      console.log(`File updated: ${event.entity_id}`);
      break;
    case 'deleted':
      console.log(`File deleted: ${event.entity_id}`);
      break;
  }
}
 
app.listen(3000);

Technical details

Request format

  • Method: POST
  • Content-Type: application/json
  • User-Agent: fairu/webhook
  • Timeout: 5 seconds

Event debouncing

Events are debounced for 5 seconds to prevent overwhelming your endpoint with rapid successive changes. If the same entity triggers multiple events within this window, only the most recent state is sent.

Event batching

Multiple events may be batched into a single request. Always iterate over the events array rather than assuming a single event per request.

Delivery

Webhook requests are processed asynchronously via a queue. Events are typically delivered within a few seconds of occurring, though delivery time may vary under high load.


Best practices

Respond quickly

Your endpoint must respond within 5 seconds or the request will time out. Perform minimal processing in your webhook handler and queue any heavy work for background processing.

// Good: Respond immediately, process later
app.post('/webhooks/fairu', async (req, res) => {
  // Queue for background processing
  await queue.add('process-webhook', req.body);
 
  // Respond immediately
  res.status(200).send('OK');
});

Handle duplicate events

While rare, network issues may cause the same event to be delivered more than once. Design your webhook handler to be idempotent—processing the same event twice should have the same result as processing it once.

// Use entity_id + event_type + timestamp as a deduplication key
const eventKey = `${event.entity_id}-${event.event_type}-${event.timestamp}`;
if (await hasProcessedEvent(eventKey)) {
  return; // Already processed
}
await markEventProcessed(eventKey);

Log incoming requests

Log all incoming webhook requests for debugging and auditing. Include the full payload, timestamp, and your processing result.

Use HTTPS

Always use HTTPS endpoints in production to ensure webhook data is encrypted in transit.

Validate the source

Consider implementing additional validation such as:

  • IP allowlisting (if Fairu provides static IPs)
  • Checking the webhook_id matches your configured webhook

Debugging

Webhook logs

Fairu logs every webhook request, including:

  • Request payload
  • Response status code
  • Response body (truncated)
  • Duration in milliseconds

Access webhook logs in Settings → Webhooks → [Your Webhook] → Logs to troubleshoot delivery issues.

Common issues

IssueSolution
Timeout errorsEnsure your endpoint responds within 5 seconds. Move heavy processing to a background queue.
Connection refusedVerify your endpoint is publicly accessible and the URL is correct.
SSL certificate errorsEnsure your SSL certificate is valid and not self-signed (in production).
401/403 errorsCheck that your authentication credentials are correct.
No events receivedVerify the webhook is active and you've subscribed to the correct events.

Testing webhooks

For local development, use a tunnel service like ngrok to expose your local endpoint:

ngrok http 3000

Then use the generated HTTPS URL as your webhook endpoint.