Skip to content
Files SDK
Esc
↑↓navigate↵open⌘Jpreview
On this page

Appwrite

Receive Appwrite storage file webhooks at files.events.webhook(), verified with the webhook's signature key.

Appwrite project webhooks report storage file events. The appwrite adapter reads the appwrite format.

Create a webhook in the console (Project → Settings → Webhooks) for the buckets.*.files.*.create and buckets.*.files.*.delete events, and copy its signature key.

import { createRouteHandler } from "files-sdk/next";
import { files } from "@/lib/files";

export const { POST } = createRouteHandler(
  files.events.webhook({
    verify: {
      secret: process.env.APPWRITE_WEBHOOK_KEY!,
      url: "https://app.example.com/api/storage-events",
    },
  })
);

Appwrite signs the webhook URL followed by the body (base64 HMAC-SHA1), so url must be exactly the URL configured in Appwrite, not one derived from the request. The signature has no timestamp; dedupe on event.id, which is Appwrite’s delivery id.

What happened to the file is in the X-Appwrite-Webhook-Events header, not the body, so Appwrite deliveries need the whole request: use webhook() or parse(request), not parse(body).

What maps to what

…files.<id>.create becomes created and …files.<id>.delete becomes deleted; updates (renames, permissions) are skipped. The key is the file’s $id, which is the key files-sdk/appwrite writes under. A project webhook can cover several buckets, so events() keeps only the adapter’s own bucket by default; pass events({ bucket: "<bucket id>" }) to pick another, or bucket: false for all of them.

Last updated on

Was this page helpful?