Skip to content

Working with master and replica contacts

How to link contacts that represent the same person across accounts, and what linking changes.

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

Before starting, ensure you have:

  1. Completed the Authentication guide and obtained your OAuth2 credentials
  2. Your Client ID from the Xama platform
  3. The contacts you want to link already created in Xama

Every contact has a replica_mode:

ModeMeaning
NORMALNot linked. Every new contact starts as NORMAL.
MASTEROne or more REPLICAs are linked to this contact. Its data represents all of them.
REPLICALinked 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 NORMAL when its last REPLICA is unlinked.
  • 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.

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}/search

Request Example

Terminal window
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

ParameterTypeDescription
querystringSearch term (email, first name, last name, or client name)
q:replica_modestringComma-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 CONTACT entities. The contact’s account_id and id are what you send when linking.
  • name is 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.

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

Terminal window
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.

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_reference is present only when replica_mode is REPLICA. On NORMAL and MASTER contacts the field is omitted, not null.
  • The MASTER itself shows "replica_mode": "MASTER".

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}/contacts

Request Example

Terminal window
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 REPLICATaken from the MASTER
id, account_id and account nameName, email and other identity fields
type and statusPrimary address
replica_mode and master_contact_referenceOnboarding and AML report status
has_documents and ComplyAdvantage monitoring

Implementation Notes:

  • NORMAL and MASTER rows are the same with or without view:master.
  • view:master is available only on the account-scoped listing shown above.
  • Filter with q:replica_mode (for example q:replica_mode=REPLICA) to list only linked 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

Terminal window
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.

Linking and unlinking return standard problem responses (application/problem+json).

StatusCause
404The client, account or contact in the path doesn’t exist, or the master target doesn’t exist
409The 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:

Casedetail starts with
Contact being patched is already linkedcontact [...] has [replicaMode=MASTER] or [replicaMode=REPLICA] … cannot be linked to another MASTER
Target contact is a REPLICAmaster contact [...] has [replicaMode=REPLICA] and thus cannot become a MASTER
Unlink on a contact that isn’t linkedcontact [...] 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_reference gives you the MASTER’s ids.
  • If the contact is already a REPLICA of a different MASTER, unlink it first, then link it again.

See the API Reference for the full request and response schemas, in particular ContactPatch, Contact.replica_mode and Problem409.