CDP REST APIAPI Reference
Merge Profiles
Merge one profile into another — the loser becomes an alias of the winner.
POST /cdp/profiles/merge explicitly merges the loser profile into the winner: the loser is
deleted and its id becomes an alias of the winner. BOTH profiles are fetched in-scope BEFORE
any write, so a merge never relies on post-filtering — either id missing aborts with 404
and zero writes. A self-merge (winnerId === loserId) and an already-merged loser are
idempotent no-ops; a loser already merged into a DIFFERENT profile is a 409.
Every write is bound to your brand's shop scope. See Tenant Isolation & Scope.
Query parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
winnerId | string | Yes | — | Body field — the surviving profile id. |
loserId | string | Yes | — | Body field — the profile id merged into the winner (its id becomes an alias). |
Response
The 200 response body:
| Field | Type | Description |
|---|---|---|
winnerId | string | |
loserId | string | |
status | 'merged' | 'noop' | |
reason | 'self' | 'already_merged' | |
aliasedLoserId | string | |
scope | string | Your brand's resolved shop domain. |
Errors
All errors share the standard envelope { "error": string, "error_description": string }.
| Status | Code | When |
|---|---|---|
400 | bad_request | The body is not valid JSON, or a required id is missing. |
401 | unauthorized | Missing or invalid API credential. |
403 | forbidden | No connected Shopify integration resolves a scope for the brand. |
404 | not_found | The winner or loser is missing or out-of-scope for the brand. |
409 | conflict | The loser is already merged into a different profile. |
405 | method_not_allowed | The request used a method other than POST. |
500 | internal_error | An unexpected error prevented the merge. |