> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Activate segments into Braze, Iterable, and Customer.io

> Connect a martech destination via the integration you already use for per-event dispatch, map segment traits onto the destination's profile object, run an on-demand object sync, and read the run history.

# Activate segments into Braze, Iterable, and Customer.io

Orbit's CDP activates segments into martech destinations as **native object writes** — the profile object each app upserts. This guide walks Braze end to end, then covers the Iterable and Customer.io deltas. For Salesforce and HubSpot, the bidirectional OAuth walk (inbound sync + outbound writeback) lives in [Connect HubSpot & Salesforce end to end](/guides/hubspot-salesforce-integration); this page is the segment-activation half.

## 1. What a martech destination is

The CRM/martech destination family has six slugs, each with a closed list of object types and a default upsert identifier:

| Destination | Object types | Default upsert identifier |
| - | - | - |
| `salesforce` | `Contact`, `Lead`, `Account` | `Email` |
| `hubspot` | `contact`, `company` | `email` |
| `braze` | `user` | `external_id` |
| `iterable` | `user` | `email` |
| `customer_io` | `person` | `id` |
| `klaviyo` | `profile` | `email` |

The `object_type` is validated against this list when you PATCH your config, so a bad target fails at config time — not mid-run. Segment-object sync is the only destination shape on this surface: it syncs a batch of segment profiles into one native object. It does not stream per-event tracking into Braze or Iterable; per-event dispatch to this same family lives on the [destinations panel](/guides/cdp-destinations).

## 2. Connect Braze via Nango

The same connected integration that powers per-event contact upsert powers the batch object sync — one connection, both paths. If your organization connected Braze on the [destinations](/guides/cdp-source-and-destinations) page, object sync can run against it with **no new auth**. Braze, Iterable, and Customer.io each route through a Nango integration id you authorize once; the upstream OAuth token lives only inside that connection, never in a sync config.

<Info>
  A run against a destination with no connected account is still recorded — every batch reports as skipped dispatch — so you can validate the mapping end to end before you wire the integration.
</Info>

## 3. Build the segment to activate

Object sync draws from one segment. Build or pick it in [CDP segments](/guides/cdp-segments) — the segment's membership is also your consent filter: only profiles whose definition you wrote reach the destination. Note the `segment_id`, you pass it in the config and on every run.

## 4. Configure the Braze mapping

Read every destination's current mapping with `GET /api/v1/cdp/crm-sync/config`. Then PATCH Braze with only the keys you want to change — the merge is scoped to that one destination:

```bash theme={null}
curl -X PATCH "https://api.orbit.devotel.io/api/v1/cdp/crm-sync/config/braze" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "object_type": "user",
    "segment_id": "seg_high_value_clickers",
    "identifier_field": "external_id",
    "field_map": {
      "user_id": "external_id",
      "email": "email",
      "first_name": "first_name",
      "last_name": "last_name",
      "lifecycle_stage": "lifecycle_stage"
    },
    "schedule_minutes": 60
  }'
```

Field-map rules (config time and run time):

* **Flattened trait paths.** Each `field_map` key is a source trait path — a flat key or a dotted path like `traits.email`, up to 5 segments. Segments named `__proto__`, `prototype`, or `constructor` are rejected outright, so a polluted key can never reach the per-record projector.
* **The identifier must be a mapped value.** `external_id` must appear as one of your `field_map` destination values (here, from the `user_id` trait), or the config is rejected — without a mapped upsert key every record would be a blind-inserted duplicate.
* **No duplicate destination fields.** Two source traits writing the same Braze attribute would silently clobber one another, so the mapping rejects it.

## 5. Run the on-demand sync

Trigger a run with `POST /api/v1/cdp/crm-sync/run/braze`:

```bash theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/cdp/crm-sync/run/braze" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "segment_id": "seg_high_value_clickers",
    "profiles": [
      { "user_id": "u_1024", "email": "ana@example.com", "first_name": "Ana" },
      { "user_id": "u_1025", "email": "ben@example.com", "first_name": "Ben" }
    ]
  }'
```

Profiles (1–5000 per request) are projected through the stored field map and chunked into upsert batches of 100. A profile whose mapped record is missing the identifier value is skipped — counted in `skipped`, never blind-inserted.

The response is the recorded run object:

```json theme={null}
{
  "id": "9c3d...",
  "destination": "braze",
  "object_type": "user",
  "segment_id": "seg_high_value_clickers",
  "requested": 2,
  "matched": 2,
  "skipped": 0,
  "batches": 1,
  "dispatched": 1,
  "status": "ok"
}
```

`status` reads `ok` (every batch upserted), `partial`, `failed`, or `skipped` (nothing matched or no connected account yet).

## 6. Iterate: Iterable and Customer.io

Same walk, two deltas:

* **Iterable** — PATCH `/api/v1/cdp/crm-sync/config/iterable` with `object_type: "user"` and the upsert key you email on: `identifier_field: "email"`. Records upsert as Iterable users.
* **Customer.io** — PATCH `/api/v1/cdp/crm-sync/config/customer_io` with `object_type: "person"` and `identifier_field: "id"` (Customer.io's canonical customer id). Records upsert as persons.

Keep each destination's identifier as one of its mapped values, exactly as in step 4.

## 7. Read the sync history

`GET /api/v1/cdp/crm-sync/runs` returns your most recent runs, newest first, capped at the last 50 per organization:

```json theme={null}
{
  "runs": [
    {
      "id": "9c3d...",
      "destination": "braze",
      "object_type": "user",
      "segment_id": "seg_high_value_clickers",
      "requested": 5000,
      "matched": 4987,
      "skipped": 13,
      "rows": { "attempted": 4987, "delivered": 4985, "rejected": 0, "failed": 2 },
      "status": "partial"
    }
  ]
}
```

Check `skipped` (profiles missing the upsert key) and `rows.failed` (per-batch provider errors, with record counts — never the profile records) to find the leg that needs a fix. The [sync run log](/guides/cdp-sync-run-log) guide walks the full reading loop.

## 8. How this differs from the Salesforce/HubSpot walk

The [HubSpot & Salesforce guide](/guides/hubspot-salesforce-integration) covers a **bidirectional** loop: inbound contact sync into the contact book plus outbound writeback, wired by admins through OAuth. Braze, Iterable, and Customer.io have no inbound half on this surface — object sync is the outbound, segment-to-object leg only, and the connection you authorized once powers both it and the per-event dispatch path.

## Related

* [CDP to CRM object sync (all six destinations)](/guides/cdp-crm-object-sync)
* [Build the source segment](/guides/cdp-segments)
* [Destinations (per-event dispatch)](/guides/cdp-destinations)
* [Decode CRM connection and dispatch errors](/troubleshooting/crm-integration-errors)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.