Webhooks

Outbound HTTP notifications when things change in your library — so your integrations react instead of polling.

Setup

Owners and admins manage endpoints under Settings → Webhooks. Each subscription has an HTTPS URL, a set of subscribed events, and a signing secret — shown once at creation, store it in your secrets vault. Use the Send test ping button to verify your receiver end-to-end.

Events

EventFires when
pingTest delivery from the UI
asset.createdFigma import, upload, or POST /api/v1/assets
asset.updatedAsset metadata edited
asset.deletedAsset deleted
collection.createdCollection created
collection.sharedCollection shared via public link
member.invitedTeammate invited
member.joinedInvitation accepted

Delivery format

Each delivery is a JSON POST:

{
  "id": "5f3c…",            // delivery id — dedup on it, retries reuse it
  "event": "asset.created",
  "organization_id": "a1b2…",
  "emitted_at": "2026-06-07T14:00:00Z",
  "data": { … }              // event-specific payload
}

With headers:

HeaderContent
X-DesignVault-EventEvent name
X-DesignVault-Delivery-IdUnique id, stable across retries
X-DesignVault-TimestampUnix seconds
X-DesignVault-Signaturet=<timestamp>,v1=<hex>

Verifying signatures

The signature is HMAC-SHA256 of `${timestamp}.${rawBody}` using your endpoint secret. Always verify before trusting a delivery, and reject timestamps older than ~5 minutes (replay protection):

import { createHmac, timingSafeEqual } from 'node:crypto'

function verify(rawBody: string, header: string, secret: string): boolean {
  const [t, v1] = header.split(',').map((p) => p.split('=')[1])
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false
  const expected = createHmac('sha256', secret)
    .update(`${t}.${rawBody}`)
    .digest('hex')
  return timingSafeEqual(Buffer.from(expected), Buffer.from(v1))
}

Retries

Respond with any 2xx within 10 seconds to acknowledge. Anything else (including timeouts) triggers retries with exponential backoff — 5s, 30s, 5m, 30m, 2h — for up to 5 attempts, then the delivery is marked failed. Owners and admins can inspect the delivery history and replay failed deliveries from Settings → Webhooks.

Good practices

  • Dedup on the delivery id — retries reuse it; process-at-most-once is your receiver's job.
  • Acknowledge fast, process async — enqueue the payload and return 200; don't do slow work inline.
  • HTTPS only — HTTP endpoints are rejected at creation.
  • Pair with the read API — the webhook tells you something changed; fetch the fresh state with GET /api/v1/assets/{id}.
Webhooks — DesignVault Docs