Brandfine Docs
SDK

Webhook handler

Framework-agnostic POST handler. Works on Astro, Next, Remix, Bun, Workers.

import { createBrandfineWebhookHandler } from '@brandfine/client/webhook'

const handler = createBrandfineWebhookHandler({
  secret: process.env.BRANDFINE_WEBHOOK_SECRET!,
  onEvent: ({ event, key }) => {
    postsCache.invalidate()
    if (event.startsWith('navigation.'))
      navigationsCache.invalidate(key ?? undefined)
  },
})

handler is a (Request) => Promise<Response> function — the standard Web Fetch API shape.

Wiring per framework

Astro

Use the adapter (handles the APIRoute shape):

import { createBrandfineWebhookRoute } from '@brandfine/client-astro'

export const POST = createBrandfineWebhookRoute({
  secret: import.meta.env.BRANDFINE_WEBHOOK_SECRET,
  onEvent: (...) => { /* ... */ },
})

Next.js (App Router)

The handler is already in Next's expected shape:

// app/api/brandfine-webhook/route.ts
import { createBrandfineWebhookHandler } from '@brandfine/client/webhook'

export const POST = createBrandfineWebhookHandler({
  secret: process.env.BRANDFINE_WEBHOOK_SECRET!,
  onEvent: (...) => { /* ... */ },
})

Remix

// app/routes/api.brandfine-webhook.tsx
import { createBrandfineWebhookHandler } from '@brandfine/client/webhook'

const handler = createBrandfineWebhookHandler({ /* ... */ })

export const action = ({ request }: { request: Request }) =>
  handler(request)

Status codes the handler returns

CodeWhenBrandfine retries
200Authenticated + onEvent returned
400Missing/malformed bodyNo
401Missing/wrong secretNo
500onEvent threwYes (with backoff)

Throwing from onEvent is the right move when invalidation itself failed (e.g., a downstream cache layer was down). The 500 tells Brandfine to retry the delivery.

Lower-level primitives

If you need custom routing:

import { verifyWebhookSecret, parseWebhookPayload } from '@brandfine/client/webhook'

// Constant-time string compare:
verifyWebhookSecret(providedFromUrl, expectedFromEnv) // → boolean

// Parse + validate the JSON envelope:
const payload = await parseWebhookPayload(request)
// throws on bad body — caller turns that into 400

On this page