Freedam

Webhooks

Webhooks deliver real-time events from Freedam to an HTTPS endpoint you control. Use them in place of polling — when an asset is uploaded, a share is created, or an operation finishes, Freedam will POST a JSON payload to your URL within seconds.

Lifecycle

  1. Register an endpoint with POST /v1/webhooks. Freedam returns a signing secret (shown once).
  2. Verify every incoming request using the X-Freedam-Signature HMAC header (see below).
  3. Acknowledge with a 2xx response within 10 seconds. Anything else is treated as a failure.
  4. Failed deliveries are retried with exponential back-off (1m, 5m, 30m, 2h, 12h). After repeated failures the endpoint is auto-disabled.

Endpoints

Method Path Description
GET /v1/webhooks List endpoints registered by the caller.
POST /v1/webhooks Create an endpoint.
GET /v1/webhooks/{id} Read endpoint config.
PUT /v1/webhooks/{id} Update url, events, or active state.
DELETE /v1/webhooks/{id} Permanently delete an endpoint.
POST /v1/webhooks/{id}/test Send a synthetic webhook.test event.
GET /v1/webhooks/{id}/deliveries List recent deliveries with status & latency.
POST /v1/webhooks/{id}/rotate-secret Generate a new signing secret.

Creating an endpoint

curl -X POST https://your-freedam-instance.com/api/v1/webhooks \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/freedam/webhook",
    "events": ["asset.created", "asset.updated", "share.created"],
    "description": "Production pipeline"
  }'

The response includes the signing_secret field once. Store it server-side — it cannot be retrieved later. If you lose it, call POST /v1/webhooks/{id}/rotate-secret.

Event payload shape

{
    "id": "evt_01HKAB...",
    "type": "asset.created",
    "created_at": "2026-05-06T10:00:00.000Z",
    "data": {
        "asset": {
            "gaid": "ast_01HKAB...",
            "title": "Hero shot Q3",
            "mime_type": "image/jpeg",
            "...": "..."
        }
    }
}

Verifying signatures

Every delivery includes:

  • X-Freedam-Signature: t=<unix-timestamp>,v1=<hex-hmac-sha256>
  • X-Freedam-Event: <event-type>
  • X-Freedam-Delivery: <delivery-uuid>

Compute HMAC-SHA256(secret, "{timestamp}.{raw-body}") and compare it to v1 in constant time. Reject the request if the timestamp is older than 5 minutes — this prevents replay attacks.

The TypeScript SDK ships a helper:

import { verifyWebhookSignature } from '@freedam/sdk';

const ok = verifyWebhookSignature({
    payload: rawBodyString,
    header: req.headers['x-freedam-signature'] as string,
    secret: process.env.FREEDAM_WEBHOOK_SECRET!,
    toleranceSeconds: 300,
});

if (!ok) {
    return res.status(400).end();
}

Available events

Event Triggered by
asset.created A new asset is ingested and ready.
asset.updated Asset metadata changes.
asset.deleted Asset is soft-deleted.
asset.restored Soft-deleted asset is restored.
collection.created A collection is created.
collection.updated A collection's name/description changes.
collection.deleted A collection is deleted.
share.created A share link is created.
share.revoked A share is revoked or expired.
upload.batch.completed An ingestion batch finishes processing.
operation.completed An async operation reaches a terminal state.
webhook.test Manually triggered via POST /webhooks/{id}/test.

Inspecting deliveries

GET /v1/webhooks/{id}/deliveries returns the most recent attempts (status code, latency, response excerpt) so you can debug your handler without grepping production logs. The same data is visible in the admin UI under API → Webhooks.

Disabling and rotating

Set is_active: false via PUT to silence an endpoint without losing its config. Rotate the secret when a teammate leaves or after a suspected leak — old signatures stop verifying immediately.

show.relatedDocs.heading

show.relatedDocs.subheading