Providers / April 25, 2026

How to receive Braze webhooks reliably (campaigns, canvases, and message events)

Braze webhook flow showing campaign and Canvas events delivered to an external endpoint

Braze "webhooks" don't work the way Stripe or GitHub webhooks do. In Braze, a webhook is a message channel — alongside email, push, SMS, and in-app — that lets a campaign or Canvas POST to an external URL when it fires. There's no static event stream like "every user signup posts to your endpoint." Instead, your marketing team configures specific campaigns or Canvases to send a webhook as their action.

This guide covers what Braze actually sends, how to configure authentication (since Braze gives you full control over the request), and how to make the channel reliable for downstream consumers.

What Braze sends

A Braze webhook request is whatever the campaign or Canvas builder configured. The request method (usually POST), the URL, the headers, and the body are all defined in the Braze UI when the webhook step is set up.

A typical configured request:

POST https://your-app.example.com/braze-webhook
Content-Type: application/json
Authorization: Bearer <token configured in Braze>

{
  "user_id": "{{ ${user_id} }}",
  "external_id": "{{ ${external_id} }}",
  "campaign_id": "{{ ${campaign_id} }}",
  "campaign_name": "{{ ${campaign_name} }}",
  "canvas_id": "{{ ${canvas_id} }}",
  "canvas_step_id": "{{ ${canvas_step_id} }}",
  "event_type": "trigger_fired",
  "trigger_event": "{{ ${trigger_event_type} }}"
}

The {{ ${...} }} syntax is Braze's Liquid templating — it pulls values from the user's profile and the firing context. The team building the campaign decides which fields to include.

This means: what your handler receives is a contract between your engineering team and your marketing team. Document the schema upfront and treat it as a versioned API.

Braze authentication: you own it

Because Braze lets the campaign builder set request headers, there's no provider-side signature scheme — you build the auth model yourself. Common patterns:

  • Bearer token — set Authorization: Bearer <token> in the campaign config; verify it in your handler
  • Custom signature — include an HMAC-SHA256 of the body in a custom header (computed in Liquid using your shared secret) and verify in your handler
  • Source IP allowlist — Braze publishes their outbound IP ranges per data center; if your edge can enforce CIDR allowlists, this works as a layered defense

The Bearer token approach is the most common and the most portable. Pair it with an unguessable URL and you've reproduced the security posture of a signed provider.

Braze's retry policy

Braze retries failed webhook requests (non-2xx, or no response within a few seconds) — the policy depends on the channel-rate-limit settings and is configurable per campaign. The retry window is finite.

This means:

  • Acknowledge fast — return 2xx in under a second; do real work async
  • Be idempotent — include a unique event identifier in the configured body (e.g. dispatch_id or a Liquid-generated UUID) and dedupe on it
  • Have a recovery story — for missed events, query Braze's Currents data export or the User API depending on what data you needed

DIY: minimal Braze webhook handler in Node

import { createHmac, timingSafeEqual } from 'crypto'

const bearerToken = process.env.BRAZE_WEBHOOK_BEARER!

export async function POST(req: Request) {
  // Bearer token check (configured in the Braze campaign settings)
  const auth = req.headers.get('authorization')
  if (auth !== `Bearer ${bearerToken}`) {
    return new Response('Unauthorized', { status: 401 })
  }

  const body = await req.text()
  const event = JSON.parse(body)

  // Idempotency on the dispatch_id you configured in the campaign body
  // ...

  queueWork(event)

  return new Response('ok', { status: 200 })
}

Production needs more:

  • A persistence layer for the per-campaign idempotency key
  • A versioning strategy for the request body shape (campaigns evolve faster than handlers)
  • Routing by campaign_id or canvas_id so different campaigns can drive different downstream actions
  • A schema-validation step at the handler edge so a campaign-config typo surfaces clearly instead of corrupting downstream state

Hooksbase: receive Braze webhooks without rebuilding the rest

Braze isn't one of Hooksbase's five pre-verified provider packs (Stripe, GitHub, Clerk, Slack, Resend), but Braze lets you configure request headers. For Hooksbase ingest, use the Hooksbase bearer ingest secret as the request Authorization header. If you need a separate Braze-specific auth check, put a small verification forwarder in front of Hooksbase.

Setup:

  1. Create a webhook in Hooksbase with your application URL as the destination
  2. In the Braze campaign or Canvas, set the webhook URL to the Hooksbase ingest URL
  3. Configure Authorization: Bearer <Hooksbase ingest secret> in the Braze campaign
  4. Keep any Braze-specific auth or schema validation in a forwarder if you need it before relay acceptance

You get:

  • Acknowledge in milliseconds to Braze, well within the channel's response budget
  • Idempotency for your destination — every dispatch includes a unique webhook-id header (Standard Webhooks-compatible) you can dedupe on, separate from the per-campaign key you configured in Braze
  • Retries with exponential backoff to your endpoint after Hooksbase accepts the event
  • Routing rules by campaign_id, canvas_id, or any payload field — send specific campaigns to specific destinations
  • Payload transforms — normalize varying body shapes from different campaigns into a canonical shape your handler expects
  • Deterministic replay — re-run a failed delivery with the same payload bytes while the payload is retained (especially valuable when a campaign-side typo or a downstream bug needs a fix-and-replay loop)
  • Delivery history and DLQ

Common Braze webhook use cases for AI agents

  • Personalization-completion agent — Braze fires the webhook when a campaign segment matches; the agent enriches the user data with deeper context and writes back to Braze via the User API for the next campaign step
  • Cross-channel orchestration agent — when a Braze campaign tries one channel and the user doesn't engage, the webhook triggers an agent that picks the next channel based on user history
  • External-action agent — when a Canvas step needs to take action outside Braze (provision a free trial, grant a feature flag, send to a third-party tool), the webhook is the bridge
  • Re-engagement decisioning agent — Braze identifies a stalled user; the webhook hands the decision off to an agent that picks the right intervention
  • Audit-and-suppression agent — every webhook from a sensitive campaign feeds an audit log and a real-time suppression check before downstream action

Where to go next

Start free at app.hooksbase.com.

Related guides