Working with master and replica contacts
Working with master and replica contacts
Section titled “Working with master and replica contacts”How to link contacts that represent the same person across accounts, and what linking changes.
Overview
Section titled “Overview”The same person often appears on more than one account. A director of three companies is a contact on each company account, and may also have an individual account of their own. Without links, each of those contacts needs its own ID verification, onboarding and AML checks.
Linking lets you nominate one contact as the MASTER and link the others to it as REPLICAs. The MASTER’s identity, onboarding and AML data then represents the person everywhere they appear.
This guide covers how to:
- Find a contact to link to
- Link a contact as a REPLICA
- Read linked contacts and their effective status
- Unlink contacts
- Handle errors returned by linking and unlinking
Prerequisites
Section titled “Prerequisites”Before starting, ensure you have:
- Completed the Authentication guide and obtained your OAuth2 credentials
- Your Client ID from the Xama platform
- The contacts you want to link already created in Xama
Replica modes
Section titled “Replica modes”Every contact has a replica_mode:
| Mode | Meaning |
|---|---|
NORMAL | Not linked. Every new contact starts as NORMAL. |
MASTER | One or more REPLICAs are linked to this contact. Its data represents all of them. |
REPLICA | Linked to a MASTER, identified by master_contact_reference. It reflects the MASTER’s data. |
You don’t set replica_mode directly. It follows from the links:
- A contact becomes a REPLICA when you link it to a MASTER.
- A contact becomes a MASTER when the first REPLICA is linked to it.
- A MASTER returns to
NORMALwhen its last REPLICA is unlinked.
Linking rules
Section titled “Linking rules”- Always patch the REPLICA, never the MASTER. This applies to linking and to unlinking.
- The contact being linked must be
NORMAL. A MASTER can’t become a REPLICA, and a REPLICA can’t be linked to a second MASTER. - The target must not be a REPLICA. Links are one level deep: there are no chains.
- The target can be on the same account or on another account of the same client, and can be
ARCHIVED. - Linked contacts (MASTER or REPLICA) can’t be moved to another account. Unlink them first.
API Endpoints and Implementation
Section titled “API Endpoints and Implementation”Find a contact to link to
Section titled “Find a contact to link to”Use search to find the contact that should become the MASTER. Filter by q:replica_mode so that only valid targets are returned: REPLICAs can’t be linked to.
Endpoint
GET /clients/{clientId}/searchRequest Example
curl -X GET "https://xamahub.xamatech.com/api/clients/{clientId}/search?query=Cooper&q:replica_mode=MASTER,NORMAL" \ -H "Accept: application/json" \ -H "Authorization: Bearer {access_token}"Query Parameters
| Parameter | Type | Description |
|---|---|---|
query | string | Search term (email, first name, last name, or client name) |
q:replica_mode | string | Comma-separated replica modes. If omitted, all modes are returned |
Response Example
{ "items": [ { "account_id": "c0faff70-785a-11f0-a2c1-8f30eeaee00b", "account_name": "Coopers Corp", "account_status": "ACTIVE", "account_type": "COMPANY", "email": "yvette@example.com", "entity": "CONTACT", "id": "c0faff71-785a-11f0-a2c1-8f30eeaee00b", "name": "Yvette Cooper", "replica_mode": "NORMAL", "status": "ACTIVE", "type": "PRIMARY" } ], "page": 1, "page_size": 100, "result_size": 1}Implementation Notes:
- Use only
CONTACTentities. The contact’saccount_idandidare what you send when linking. nameis the first and last name combined into one string. Search results have no separate name fields, so compare names with that in mind.- Prefer a contact that has already been through onboarding and AML checks as the MASTER. Its data is what the REPLICAs will show.
Link a contact as a REPLICA
Section titled “Link a contact as a REPLICA”Patch the contact that should become the REPLICA, and send the MASTER’s account and contact id in master.
Endpoint
PATCH /clients/{clientId}/accounts/{accountId}/contacts/{contactId}{accountId} and {contactId} identify the contact becoming the REPLICA.
Request Example
curl -X PATCH "https://xamahub.xamatech.com/api/clients/{clientId}/accounts/{accountId}/contacts/{contactId}" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer {access_token}" \ -d '{ "master": { "account_id": "c0faff70-785a-11f0-a2c1-8f30eeaee00b", "contact_id": "c0faff71-785a-11f0-a2c1-8f30eeaee00b" } }'Response
204 No Content on success. See Errors for failures.
What linking changes
- The REPLICA reflects the MASTER’s identity, onboarding and AML data.
- Automatic AML refresh is turned off for the REPLICA.
- The REPLICA’s own reports and documents are kept, not deleted. They are hidden behind the MASTER’s data while linked, and show again after unlinking.
- Any client onboarding progress for the REPLICA’s account is recalculated.
Read a linked contact
Section titled “Read a linked contact”Fetch the contact to confirm the link.
Endpoint
GET /clients/{clientId}/accounts/{accountId}/contacts/{contactId}Response Example (abbreviated)
{ "id": "7a1d2c40-8e2b-11f0-a2c1-8f30eeaee00b", "account_id": "5d0e9b20-8e2b-11f0-a2c1-8f30eeaee00b", "first_name": "Yvette", "last_name": "Cooper", "replica_mode": "REPLICA", "master_contact_reference": { "account_id": "c0faff70-785a-11f0-a2c1-8f30eeaee00b", "contact_id": "c0faff71-785a-11f0-a2c1-8f30eeaee00b" }}Implementation Notes:
master_contact_referenceis present only whenreplica_modeisREPLICA. OnNORMALandMASTERcontacts the field is omitted, notnull.- The MASTER itself shows
"replica_mode": "MASTER".
List contacts with their effective status
Section titled “List contacts with their effective status”When listing an account’s contacts, set view:master=true to see each REPLICA with its MASTER’s data, without fetching every MASTER separately.
Endpoint
GET /clients/{clientId}/accounts/{accountId}/contactsRequest Example
curl -X GET "https://xamahub.xamatech.com/api/clients/{clientId}/accounts/{accountId}/contacts?view:master=true" \ -H "Accept: application/json" \ -H "Authorization: Bearer {access_token}"With view:master=true, each REPLICA row:
| Kept from the REPLICA | Taken from the MASTER |
|---|---|
id, account_id and account name | Name, email and other identity fields |
type and status | Primary address |
replica_mode and master_contact_reference | Onboarding and AML report status |
has_documents and ComplyAdvantage monitoring |
Implementation Notes:
NORMALandMASTERrows are the same with or withoutview:master.view:masteris available only on the account-scoped listing shown above.- Filter with
q:replica_mode(for exampleq:replica_mode=REPLICA) to list only linked contacts.
Unlink contacts
Section titled “Unlink contacts”To remove a link, patch the REPLICA with both master fields set to empty strings.
Endpoint
PATCH /clients/{clientId}/accounts/{accountId}/contacts/{contactId}Request Example
curl -X PATCH "https://xamahub.xamatech.com/api/clients/{clientId}/accounts/{accountId}/contacts/{contactId}" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer {access_token}" \ -d '{ "master": { "account_id": "", "contact_id": "" } }'Response
204 No Content on success. The REPLICA returns to NORMAL. If it was the MASTER’s last REPLICA, the MASTER also returns to NORMAL.
Sending an unlink for a contact that isn’t linked fails with 409 Conflict.
Implementation Notes:
- After unlinking, the contact shows its own reports and documents again.
- Automatic AML refresh is not turned back on by unlinking. Re-enable it if the contact needs ongoing screening.
Errors
Section titled “Errors”Linking and unlinking return standard problem responses (application/problem+json).
| Status | Cause |
|---|---|
404 | The client, account or contact in the path doesn’t exist, or the master target doesn’t exist |
409 | The contact is already linked, the target is a REPLICA, or an unlink was sent for a contact that isn’t linked |
The 409 responses for linking and unlinking don’t currently include a problem type. To tell them apart, match the start of detail:
| Case | detail starts with |
|---|---|
| Contact being patched is already linked | contact [...] has [replicaMode=MASTER] or [replicaMode=REPLICA] … cannot be linked to another MASTER |
| Target contact is a REPLICA | master contact [...] has [replicaMode=REPLICA] and thus cannot become a MASTER |
| Unlink on a contact that isn’t linked | contact [...] is not linked |
Example
{ "title": "CONFLICT", "status": 409, "detail": "master contact [clientId=…] [accountId=…] [contactId=…] has [replicaMode=REPLICA] and thus cannot become a MASTER"}Implementation Notes:
- If the target is a REPLICA, link to its MASTER instead. The REPLICA’s
master_contact_referencegives you the MASTER’s ids. - If the contact is already a REPLICA of a different MASTER, unlink it first, then link it again.
Reference
Section titled “Reference”See the API Reference for the full request and response schemas, in particular ContactPatch, Contact.replica_mode and Problem409.