---
title: "Merge two contacts"
method: POST
path: "/v1/contacts/merge"
---

# Merge two contacts

`POST /v1/contacts/merge`

Merges two contacts into one. The primary contact retains its ID; the duplicate is soft-deleted.

**[Required scopes](/using-the-api/scopes/):** `contacts:update` + `contacts:delete`

**[Rate limit category](/using-the-api/rate-limits/):** Write

## Headers

- `Lightfield-Version` '2026-03-01', required

## Request body

- object
  - `primaryId` string, required — ID of the record to keep.
  - `duplicateId` string, required — ID of the duplicate record to merge into the primary and then discard.
  - `fieldResolutions` object — Per-field resolution overrides keyed by attribute slug.
  - `options` object
    - `multiSelectUnion` boolean — When true, multi-select fields are merged by union rather than primary-takes-all.

## Response `200`

OK

- MergeMergeContactsResponse
  - `merge` object, required
    - `id` string, required — Unique identifier for the merge operation.
    - `status` string, required — Current status of the merge: `cleanup_pending`, `done`, or `failed`.
  - `primary` object, required
    - `id` string, required — Unique identifier for the entity.
    - `createdAt` string, required — ISO 8601 timestamp of when the entity was created.
    - `updatedAt` string, nullable, required — ISO 8601 timestamp of when the entity was last updated, or null.
    - `httpLink` string, nullable, required — URL to view the entity in the Lightfield web app, or null.
    - `externalId` string, nullable — External identifier for the entity, or null if unset.
    - `fields` object, required — Map of field names to their typed values. System fields are prefixed with `$` (e.g. `$name`, `$email`); custom attributes use their bare slug.
    - `relationships` object, required — Map of relationship names to their associated entities. System relationships are prefixed with `$` (e.g. `$owner`, `$contact`).
  - `summary` object, required
    - `fieldWriteCount` integer, required — Number of attribute fields written onto the primary record.
    - `syncRepointedCount` integer, required — Number of related records re-pointed from the duplicate to the primary.
    - `warnings` string[], required — Non-fatal warnings from the merge (e.g. skipped transfers).

## Other responses

- `400` — 400
- `401` — 401
- `403` — 403
- `404` — 404
- `409` — 409
- `415` — 415
- `422` — 422
- `429` — 429
- `500` — 500
- `501` — 501
- `503` — 503
- `504` — 504

---

[API](https://skmtc.net/lightfld/apis/api-reference.md) · [All operations](https://skmtc.net/lightfld/apis/api-reference/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/lightfld/api-reference/versions/93b6c5de5463/schema)
