Braze to Kafka: How to Move Your Data

Move Braze into Kafka with Airbyte. Why this carries campaign aggregates rather than user events, what UUID keying costs you, and when to skip the bus entirely.

Summarize with AI:

Moving Braze into Kafka puts campaign and canvas performance somewhere several systems can read it at once. Braze has an API but no way to broadcast, so every service that wants this data today holds its own key and makes its own calls, against rate limits that vary by endpoint. A topic per stream replaces that with one pipeline and any number of consumers.

This guide covers the managed path with Airbyte. Two things shape the build, and the first one surprises people: this connector carries campaign structure and aggregated analytics rather than a per-user event firehose, and it fills topics on a schedule rather than in real time.

Braze to Kafka at a glance:

CapabilitySupportedWhat it means for this pipeline
StreamsThirteenCampaigns, canvases, cards, segments, their analytics and daily KPIs
Sync modesTwoFull refresh overwrite, or incremental append
Message formatJSON onlyNo Avro, so a schema registry is not part of this design
Message keyAirbyte UUIDNot the campaign or canvas ID, so ordering per entity is not guaranteed
TopicsCreated in advanceThe pipeline writes to them, it does not create them

Why move data from Braze to Kafka?

Two situations account for most of these pipelines.

The first is fan-out. Marketing performance is wanted in more than one place: a warehouse for reporting, a dashboard service, something that watches for a campaign underperforming. Pointing each of them at the Braze API means several keys to rotate and several callers competing against rate limits that differ per endpoint. One pipeline into topics means one caller and as many consumers as you like, each reading at its own pace.

The second is feeding services rather than analysts, where something downstream reacts to segment membership or campaign status rather than charting it. The test is simply how many consumers you have. With one warehouse at the other end, the bus earns nothing and adds a moving part, so Braze to BigQuery is the shorter road. Kafka pays for itself at three or four consumers, not at one.

What do you need before you start?

Four things, and the first two live in two different corners of the Braze dashboard:

A REST API key. Generated from the Braze dashboard under the Developer Console, in API Settings. Give it the permissions the streams you want require and no more, since a key with everything enabled is a liability sitting in a pipeline configuration. The Braze source documentation sets out both values you need.

Your SDK endpoint URL. This is not the same screen as the key. It sits under Manage Settings, then Settings, then your app, listed as the SDK Endpoint. Braze instances are regional, so a wrong endpoint here fails in a way that reads like a credential problem rather than an address problem.

Topics, created before you sync. The destination writes to topics that already exist rather than creating them, so decide your naming and partition count now. One topic per stream is the usual arrangement and keeps consumers from filtering out data they never wanted.

An honest count of your consumers. Worth doing before the work rather than after. A bus with one reader is a warehouse pipeline with extra steps, and this is the cheapest moment to notice that.

If your organisation restricts access by IP, add the Airbyte Cloud IP addresses to the allow list before you begin.

How do you build a Braze to Kafka pipeline in Airbyte?

Step 1: Create the topics and decide their partitioning

Nothing in this pipeline creates topics for you, so a sync pointed at a topic that does not exist fails rather than improvising. Create one per stream, name them so a consumer can tell campaigns from campaign analytics at a glance, and set partition counts and retention deliberately. Retention matters more than usual here, because if a consumer is offline longer than your retention window it misses that data permanently.

Step 2: Configure the Braze source

Click Sources in the left navigation, then New Source, and select Braze, following adding a source. Supply the URL, the REST API key and a start date. Select only the streams your consumers asked for, since rate limits differ by endpoint and there is no reason to pay for segment analytics nobody reads.

Step 3: Configure the Kafka destination

Click Destinations, then New Destination, and select Kafka, following adding a destination. Supply the bootstrap servers, your security protocol and the topic configuration. Output is JSON and only JSON, so if your platform standardises on Avro with a schema registry, this pipeline sits outside that convention and your consumers need to know it.

Step 4: Create the connection and pick the sync mode carefully

Click Connections, then New connection, select your streams and a sync mode. The connector offers full refresh overwrite and incremental append, and the choice reads differently against a log than against a table. Full refresh republishes every record each run, so a topic accumulates a complete copy per sync and consumers must deduplicate or treat only the latest batch as current.

Schedule for what the data is rather than out of habit. Daily KPI streams update once a day, so a fifteen-minute sync produces fourteen identical batches and a great deal of noise for your consumers to discard.

What does this connector actually send you?

Thirteen streams, and they divide into three kinds. There is structure: campaigns, canvases, cards and segments, describing what marketing has built. There are the matching analytics streams for each of those. And there are daily KPI streams covering new users, active users and app uninstalls.

What is not here is the thing people often assume a Braze pipeline into Kafka means. The analytics streams are aggregated series and the KPI streams are daily rollups, so this is not a per-user event firehose arriving message by message as customers open emails. If that is what a consuming service needs, this connector is the wrong mechanism and Braze's own export and webhook features are the place to look.

Knowing that early changes what you build. Aggregates and configuration are perfectly good things to broadcast, and several consumers reading campaign performance from a topic is a sound design. It is just a periodic publication rather than a stream, and describing it accurately to the teams consuming it saves somebody writing a service that expects individual events to arrive.

Why can't consumers rely on ordering per campaign?

Because messages are keyed by an Airbyte-generated UUID rather than by anything from Braze. Kafka assigns partitions from the message key, and ordering is guaranteed only within a partition, so two updates to the same campaign can land on different partitions and be consumed out of order by anything reading in parallel.

For much of this data that does not matter. A daily KPI row is a fact about a day and carries its own date, so order of arrival is irrelevant. It matters when a consumer maintains current state per campaign or per segment, because applying an older record after a newer one leaves that state wrong with nothing to signal it.

The fix is a repartition step: read the topic, rekey on the campaign or canvas identifier, write to a second topic, and let stateful consumers read that one. The message value carries what you need for this, since each message wraps the record alongside its identifier, the extraction timestamp and the stream name. That envelope is also worth flagging to consumers in advance, because the Braze fields sit nested inside it rather than at the top level, and a consumer written against the raw Braze API shape will not find them where it expects.

Frequently asked questions

Does this stream Braze activity in real time?

No. Syncs run on a schedule and publish in batches, so latency is whatever interval you set. Data lands in Kafka, which is not the same as data streaming into Kafka.

Will the pipeline create my topics?

No, they must exist first. Create them with the partition count and retention you want before the first sync, rather than discovering the requirement through a failure.

Can I use Avro and a schema registry?

Not through this destination, which produces JSON only. On a platform built around Avro contracts, this pipeline is an exception, and it is better to agree that up front than to have a consuming team discover it.

Why is my record wrapped in something?

Each message carries an envelope holding the record identifier, the extraction timestamp and the stream name, with the Braze data nested inside. Consumers need to read through that envelope rather than expecting the raw API shape.

Can I do this without writing code?

The pipeline, yes, and it is entirely UI-driven. The consumers are your own code, and if any of them needs ordering per campaign you will also need a repartitioning step, which is real work rather than configuration.

Get your Braze data into Kafka

Count your consumers first, because one of them does not justify a bus. Create topics with deliberate retention before the first sync, tell consuming teams that messages are JSON in an envelope and keyed by a UUID rather than by campaign, and add a repartition step for anything that keeps state per entity. Above all, describe this to its consumers as periodic campaign aggregates rather than a stream of user activity, because that is what it is.

Airbyte's connector catalog includes 600+ pre-built connectors, so marketing data can reach every system that needs it from a single pipeline. For the same source into a lakehouse, see Braze to Databricks, and for a comparable customer platform onto the same bus, Hubspot to Kafka.

Start syncing now →

Integrate with 700+ apps using Airbyte

Move data from 700+ sources into warehouses, lakes, and beyond. Set up pipelines in minutes with pre-built connectors and the Connector Builder.