Salesforce and Braze Integration Guide
A step-by-step, vendor-neutral guide to planning and building a Salesforce and Braze integration, with a field mapping table and an event schema example.

This guide walks through a Salesforce and Braze integration from first workshop to steady-state monitoring. It is deliberately generic: your objects, volumes, contract limits and consent rules will differ, and each step should be checked against current Salesforce and Braze documentation. The architecture behind it is on Salesforce and Braze integration and the reference architecture page.
Step 1: Discovery
Start with use cases, not fields. For each one, write down the trigger, the data needed, the channel, who owns the outcome, and how fresh the data must be. Typical starting points are a welcome journey for new customers, suppressing promotions for people with an open case, and alerting sales when a lead becomes engaged.
Then collect the facts that shape the design:
- Volumes: records changed per day in Salesforce, events per day from apps, and peaks.
- Contract limits: Braze documents a burst limit on
/users/trackof 3,000 requests per three seconds for customers with data points in their pricing; other customers' limits are set by contract. Check your Salesforce org's API limits too. - Existing tools: middleware, a warehouse, or an existing connector.
- Owners: a named person for Salesforce, Braze, the integration and consent.
Step 2: Identity
Decide which identifier links a Salesforce person to a Braze profile, and when it is set.
- Braze's
external_id"allows you to identify the same user profile across multiple devices". Braze discourages email or hashed email as theexternal_id, and advises against assigning one before you can uniquely identify the person. Identified users cannot be reverted to anonymous. - Braze's B2B data model guide maps Salesforce Lead and Contact IDs to user aliases, and Accounts and Opportunities to Catalogs.
- When an anonymous user is identified with an
external_idthat already exists, Braze merges eligible fields into the known profile, and the known profile wins conflicts. Plan for that in testing. /users/mergehandles duplicates, up to 50 merges per request, asynchronously. Merges are not reflected in Currents, so downstream analytics need their own handling.
Write the rules down, including what happens when a Lead converts to a Contact.
Step 3: Consent
Pick one system of record per channel and subscription group. In Braze:
- Email has global states: "Opted-in", "Subscribed" (the default for new profiles) and "Unsubscribed".
- SMS has no global state, only per-group status. SMS, WhatsApp and LINE require subscription groups.
- Braze does not automatically change a push state to Unsubscribed.
- Hard bounces do not unsubscribe a user.
Changes can be written with POST /email/status or the subscription group endpoints, which take up to 50 users per request and share a limit of 5,000 requests per minute. Braze emits Currents events for global and group state changes; Currents has no Salesforce destination, so those opt-outs reach Salesforce only through your integration layer, via storage or the Custom HTTP Connector. Record your rules in the consent requirements worksheet and check them with your legal adviser.
Step 4: Field mapping
Map only what a use case needs. Braze string attributes can be up to 255 characters, and custom attribute types are boolean, number, string, array, time, object and array of objects.
Example field mapping (illustrative)
| Salesforce source | Braze target | Type | Direction | Notes |
|---|---|---|---|---|
| Contact ID | external_id, or a user alias | string | Salesforce to Braze | Set once; never email |
| First name | first_name | string | Salesforce to Braze | Standard attribute |
| Account industry | account_industry | string | Salesforce to Braze | Up to 255 characters |
| Open case count | open_case_count | number | Salesforce to Braze | Used to suppress promotions |
| Customer since | customer_since | time | Salesforce to Braze | ISO 8601 |
| Email opt-out field | email_subscribe or /email/status | state | Owner's direction | Follows the consent owner |
| Lead stage | Lead_Stage__c on Lead | picklist | Braze to Salesforce | As in Braze's community webhook example |
Step 5: Event schemas
Agree event names, required properties and a version before developers start, and use the same names on iOS, Android, web and server. Braze custom events can carry properties; purchases use reserved keys such as product_id, price, currency and quantity.
{
"attributes": [
{
"external_id": "0035g00000AbCdE",
"account_industry": "Retail",
"open_case_count": 1
}
],
"events": [
{
"external_id": "0035g00000AbCdE",
"name": "trial_started",
"time": "2026-10-22T09:30:00Z",
"properties": {
"plan": "standard",
"source": "salesforce",
"schema_version": 1
}
}
]
}Step 6: Sync design
Choose a path per data type:
- Urgent CRM changes: Salesforce Change Data Capture or Platform Events, read through the Pub/Sub API by your integration layer, then batched into
/users/track(up to 75 objects per request). High-volume change events are retained for 72 hours, which sets your replay window. - Bulk or modelled data: a warehouse plus Braze Cloud Data Ingestion, which syncs as often as every 5 minutes.
- Writeback to Salesforce: Canvas webhooks or Currents (via the Custom HTTP Connector or storage) into your integration layer, which writes summaries to Salesforce. Currents lists no Salesforce destination.
Build in idempotency, a dead-letter queue, and backoff on HTTP 429 using the X-RateLimit-Retry-After header. Do not retry 401 or 403; fix the key or permission. See integration error handling.
Step 7: Testing
Test in a Salesforce sandbox and a Braze test workspace with synthetic data:
- Identity: new user, returning user, converted lead, duplicate contact.
- Consent: opt-out in each system, reaching the other within the agreed time.
- Volume: a peak-day replay to confirm you stay inside rate limits.
- Failure: expired credentials, Braze 429s, Salesforce validation errors, and a consumer that is offline for hours.
Step 8: Rollout
Backfill first, then switch on incremental feeds. Launch one journey to a small audience, compare counts in both systems daily, and widen only when they match. Keep a rollback plan that stops the feeds without losing queued changes.
Step 9: Monitoring
Watch sync lag, error rates by type, dead-letter queue depth, count parity between systems and unsubscribe parity. Give each alert a named owner and a runbook entry.
Checklist
- 01
Use cases written
Trigger, data, channel, owner, freshness.
- 02
Identity agreed
external_id and aliases, conversion and merge rules.
- 03
Consent owner per channel
Signed off, with sync timings.
- 04
Mapping and schemas versioned
Stored with the code.
- 05
Sync paths chosen
Events, warehouse and writeback.
- 06
Tests passed
Identity, consent, volume and failure.
- 07
Monitoring live
Alerts with owners.
Questions we hear
Do we need middleware?
What identifier should we use?
How do we handle Braze rate limits?
Related
Integration services
Have us scope and build it
→Braze data activation
All Braze data paths
→Event-driven architecture
Change events and consumers
→Data dictionary template
Record your mappings
→Sources
Get help with your integration plan
Share your use cases and volumes. We can review your plan or run discovery with you.




