Braze Currents
The Braze Currents loader streams your Braze engagement and behavioral events into your warehouse in near-real time. Braze Currents is Braze’s data-export stream; using its Custom HTTP connector, Braze POSTs event batches to a Zeotap endpoint, and each event is durably captured and loaded into your warehouse — no polling or schedule required.
Use it to bring message-engagement events (email opens, push sends, in-app clicks) and behavioral events (custom events, purchases, sessions) into Zeotap so you can model and segment on them alongside the rest of your CDP data.
When to Use It
- You use Braze and have Currents enabled on your account.
- You want push-based, near-real-time ingestion of Braze events into your warehouse.
- You want Braze’s universal event fields as typed columns while keeping event-specific and custom fields queryable.
For pulling Braze user profiles or segments on a schedule, use the Braze loader instead — it is a separate, pull-based loader.
How It Works
- Braze’s Custom HTTP Currents connector sends a
POSTrequest with a batch of events ({"events":[...]}) to the Zeotap receiver, authenticating with a write key as a Bearer token. - The receiver durably accepts the events and responds
2xximmediately. - Accepted events are buffered on a durable event stream, tagged with the loader they belong to.
- An always-on consumer batches events and loads them into the loader’s configured warehouse.
Because the receiver acknowledges only after events are durably stored, a success response means they will be loaded — Braze does not need to resend them.
Prerequisites
- A Braze account with Currents enabled (Currents is a paid add-on; contact your Braze account team if it is not available).
- A connected warehouse to load events into (BigQuery, Snowflake, Databricks, or ClickHouse).
Create the Loader
- In Zeotap, go to Loaders and click Add Loader.
- Choose Braze Currents.
- Select the Target Warehouse and Schema where events should land.
- Optionally set a Target Table name (defaults to
braze_currents_events). - Save the loader.
| Field | Required | Description |
|---|---|---|
| Target Warehouse | Yes | The warehouse source that received events are loaded into. |
| Schema | Yes | The schema/dataset that holds the events table. |
| Target Table | No | The warehouse table Currents events land in. Defaults to braze_currents_events. Use a distinct name per loader if you run more than one in the same schema. |
Mint a Write Key
Requests authenticate with a write key — a per-loader credential you manage in the UI. Braze sends it as a Bearer token.
- Open your Braze Currents loader.
- In the Write Keys section, click Create Key and give it a name (e.g.
Braze Production). - Copy the generated key — you will paste it into Braze as the Bearer token.
You can create multiple keys per loader and revoke any key at any time from the same screen. Revocation takes effect within a few minutes (the receiver briefly caches key lookups).
Configure Braze
Set up the export on the Braze side — Zeotap does not configure Braze for you (Braze has no public API to create Currents connectors).
- In Braze, go to Partner Integrations → Data Export → Currents and create a new Currents export.
- Choose the Custom HTTP (HTTP / JSON) export type.
- Set the endpoint URL to the Endpoint URL shown on the loader page (
https://<your-push-host>/v1/push/batch). - Under Authorization, choose Bearer Token and paste one of your write keys.
- Select the event types you want to export.
- Launch the export. Events begin flowing into your warehouse.
What Braze Sends
Braze POSTs batches (up to 100 events per request) to the batch endpoint:
POST https://<your-push-host>/v1/push/batch
Authorization: Bearer YOUR_WRITE_KEY
Content-Type: application/json
{
"events": [
{
"id": "6a1b...",
"event_type": "users.messages.email.Open",
"external_user_id": "user-123",
"time": 1700000000,
"campaign_id": "abc123",
"campaign_name": "Welcome"
}
]
}The receiver also accepts the write key via the X-Write-Key header, HTTP Basic Auth username, or a ?writeKey= query parameter — useful when testing with curl — but Braze’s Custom HTTP connector uses the Bearer token.
How Data Lands in the Warehouse
All Currents events land in a single table (braze_currents_events by default). Braze’s Custom HTTP payload carries no per-event type discriminator, so events are not split into per-type tables; instead, universal fields are promoted to typed columns and everything else is preserved as JSON — lossless and tolerant of Braze schema changes and per-account custom fields.
| Column | Type | Description |
|---|---|---|
received_at | timestamp | When the receiver durably accepted the event (partition column). |
loader_id | string | Which loader produced the row — keeps rows attributable if two loaders share a table. |
message_id | string | Pipeline dedup key (at-least-once delivery), independent of Braze’s id. |
id | string | Braze’s event id. |
event_type | string | The Currents event type (e.g. users.messages.email.Open). |
user_id | string | Braze user id (braze_id). |
external_user_id | string | Your external user id. |
time | timestamp | The event time reported by Braze. |
app_id, app_group_id | string | App / app-group identifiers. |
campaign_id, campaign_name | string | Campaign identifiers, when present. |
canvas_id, canvas_name | string | Canvas identifiers, when present. |
message_variation_id, dispatch_id | string | Message variation / dispatch identifiers. |
platform | string | Device platform, when present. |
properties | json | Event-specific and custom fields not promoted to a typed column. |
raw | json | The complete original event, exactly as Braze sent it. |
Fields specific to a given event type (and any custom fields) live inside properties; the full event is always preserved in raw. Extract them downstream in a model using your warehouse’s JSON functions — for example, in BigQuery:
SELECT
event_type,
external_user_id,
time,
JSON_VALUE(properties, '$.button_id') AS button_id
FROM braze_currents_events -- your loader's target table
WHERE event_type = 'users.messages.inappmessage.Click'Delivery Semantics
Delivery is at-least-once. Every acknowledged event is guaranteed to reach the warehouse, but under Braze retries or transient failures the same event may occasionally be loaded more than once. Deduplicate downstream on the event id in a model if you need exactly-once semantics.
Troubleshooting
| Issue | Resolution |
|---|---|
401 Unauthorized in Braze | The write key is missing, malformed, or revoked. Confirm the Bearer token in Braze matches an active write key on the loader. |
400 Bad Request | The body is not valid JSON or not a recognized batch shape. Braze’s Custom HTTP connector sends {"events":[...]}, which is accepted; confirm the connector type is Custom HTTP. |
| Events accepted but not in the warehouse yet | Loading is batched, so there is a short delay between acknowledgement and the row appearing. Confirm the loader’s target warehouse and schema are correct. |
| A field I expected isn’t its own column | Only universal fields are promoted to typed columns. Event-specific and custom fields are in the properties JSON column, and the full event is in raw. |
| No events arriving | Confirm the Currents export is launched in Braze (not just saved), the endpoint URL is exactly the one shown on the loader page, and the selected event types are actually being generated. |
| Duplicate rows | Expected under at-least-once delivery. Deduplicate downstream on the event id. |
Next Steps
- Create a Model over the loaded events table.
- Build an Audience from the modeled data.