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
| Code | When | Brandfine retries |
|---|---|---|
| 200 | Authenticated + onEvent returned | — |
| 400 | Missing/malformed body | No |
| 401 | Missing/wrong secret | No |
| 500 | onEvent threw | Yes (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