Skip to main content

CDP to ERP object sync

Object sync activates a CDP segment into your ERP or finance system as native object writes — NetSuite Customers or Contacts, SAP S/4HANA Business Partners or Customers, Workday Customers or Contacts, QuickBooks Customers. Records are upserted on an identifier field you choose, on the cadence you set. This is the reverse-ETL path: the segment you build in the CDP becomes the source, and the ERP object becomes the destination. Object sync is the ERP sibling of CDP to CRM object sync — the same operator surface, aimed at finance and ERP master data instead of sales and martech objects.

1. Destinations and object types

Object sync targets four ERP and finance destinations, each with a closed list of native object types: The object_type you set is validated against this list when you PATCH your config, so a target the destination cannot accept fails fast at config time, not at run time.
Distinguish the two sync directions this surface sits beside: the per-event destinations panel streams individual CDP events to connected apps, and warehouse exports move tables in and out of your data warehouse. Object sync exists for the segment-level batch case — “this segment, into that ERP object” — with an upsert key so re-runs update in place instead of duplicating records.
Connect the destination first from the destinations page — object sync can only dispatch against a destination your organization has connected. No credentials are accepted on the object-sync surface; the config carries only a connection identifier, and the upstream OAuth token stays inside your connected integration.

2. Configure a mapping

Read the config for every destination with GET /api/v1/cdp/erp-sync/config. It returns one entry per destination with its current mapping, the object types it accepts, the default upsert identifier, and the last sync outcome. To create or update a mapping, PATCH the destination with only the keys you want to change — the merge is scoped to that destination, so sibling destinations and every other organization setting are preserved. The shape is PATCH /api/v1/cdp/erp-sync/config/{destination} with {destination} one of the four ids above:
The identifier_field must appear as one of the values in your field_map. The config is rejected otherwise (400 VALIDATION_ERROR), because without a mapped key every record would be blind-inserted as a duplicate in your ERP system. Two source traits writing to the same destination field are rejected for the same reason.

3. Run a sync

Trigger an on-demand run with POST /api/v1/cdp/erp-sync/run/{destination}:
  • segment_id (required, up to 200 chars) labels which segment the profiles belong to; it is recorded on the run.
  • profiles is the batch of profiles to project through the stored field map (1 to 5000 per request).
The destination must be configured and enabled first — a run against an unconfigured destination returns 409 (DESTINATION_NOT_ENABLED until it is enabled, FIELD_MAP_NOT_CONFIGURED until a field map exists). The stored map and identifier are re-validated at run time as well. The response is the recorded run object:
Records are grouped into batches of up to 100 and upserted through your connected integration. The skipped-without-identifier rule: a profile whose mapped record has a missing or empty upsert-key value is skipped — never blind-inserted — and counted as rejected in the run’s rows breakdown. status reads:
  • ok — every batch upserted.
  • partial — some batches upserted, some failed.
  • failed — every batch failed.
  • skipped — nothing to dispatch (no matched records, or no connected account wired yet).
A run against a destination with no connected account is still recorded — every batch reports as dispatch_skipped — so you can validate the mapping end to end before you wire the integration.

4. Read the run history

GET /api/v1/cdp/erp-sync/runs returns the most recent runs, newest first. The history is capped at the last 50 runs per organization; older runs roll off as new ones land. Use it the same way you use the sync run log: shape the run, check rows.rejected (profiles skipped for a missing upsert key) and dispatch_failures (per-batch provider errors, with record counts — never the profile data) to find the leg that needs a fix.

5. Where the config lives (no migration)

Object-sync config and run history live in your organization’s settings as structured data — the same storage pattern the CRM object sync uses. There is no schema migration and no new table to manage:
  • A PATCH merges only the keys you send, under the destination you named — sibling destinations and unrelated settings are never touched.
  • Run history is a bounded, newest-first list; the cap keeps the record small and self-pruning.
Object sync activates a segment you defined, through a connection you authorized. The decision to sync, and the cadence, are entirely your organization’s controls:
  • Config changes and runs are written to the audit log with the destination and the operation counts — never the profile records themselves.
  • Runs record counts (matched, skipped, batches, dispatch outcomes), not profile payloads. Failed batches keep the provider error message and the batch’s record count only.
If you operate under a consent regime, the segment’s membership is the filter that decides whose data reaches the ERP system — keep the segment definition aligned with your subscribers’ consent, as you would for any other activation surface (erasure propagation covers the delete path).