---
title: "Merge the duplicate groups a completed scan found"
method: POST
path: "/business/contacts/dedupe-merge"
tags: ["Contacts"]
---

# Merge the duplicate groups a completed scan found

`POST /business/contacts/dedupe-merge`

## Request

- Base URL: `https://api.tryfuse.ai/api/v1`
- URL: `https://api.tryfuse.ai/api/v1/business/contacts/dedupe-merge`
- Auth: HTTP basic

Merges the duplicate groups a completed scan found — every group, or just the `groupIds` subset (16-hex `groupId` values from the scan result). Async: 202 returns a `jobId`; poll `GET /business/contacts/dedupe-jobs/{jobId}` until `status` is `completed`, then read `mergeResult` for the totals. Within each group the surviving contact is chosen by the merge contract (a Fuse contact beats a custom one; among custom-only groups the most recently created wins), its empty fields are filled from the other members, all emails and phones are combined, custom-column values are carried over, and the losing contacts are archived with their list memberships repointed to the survivor — every list that held a duplicate ends up holding the surviving contact instead. Merging cannot be undone. Two Fuse contacts with conflicting identities (different PDL ids or different LinkedIn URLs) are never combined, even when the scan grouped them; such groups are split or skipped, so `mergeResult.mergedGroups` can be lower than the number of groups submitted. The scan job must be `completed` (409 SCAN_NOT_COMPLETED while it still runs) and is consumed as stored — unknown `groupIds` merge nothing. Rate limit: 120 requests per minute, 10,000 per day on the contacts bucket, which every /business/contacts endpoint shares.

Errors:
- `404` `SCAN_NOT_FOUND` — No dedupe scan job with that id (it may have expired or belong to another workspace).
- `409` `SCAN_NOT_COMPLETED` — The scan is still running — poll it until status is completed, then retry.
- `422` `SCAN_HAS_NO_GROUPS` — The scan completed but found no duplicate groups; there is nothing to merge.
- `422` `VALIDATION_FAILED` — scanJobId is not a 24-hex id, or groupIds carries something other than 1-200 unique 16-hex ids.
- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the contacts bucket, which every /business/contacts endpoint shares; retry after Retry-After.
- `500` `UNEXPECTED_ERROR` — The request could not be completed; quote request_id to support.

Requires one of the following token scopes: contacts.

## Request body

- object
  - `scanJobId` string, required: Id of a completed dedupe scan job — the `jobId` returned by POST /business/contacts/dedupe-scan.
  - `groupIds` string[]: Optional subset of the scan's groups to merge, by `groupId` (16-hex ids from the scan result's `groups`). Omit it to merge every group the scan found.

## Response `202`

Success

- object
  - `jobId` string, required: Id of the merge job; poll GET /business/contacts/dedupe-jobs/{jobId}.

## Other responses

- `400`: Error
- `401`: Error
- `402`: Error
- `403`: Error
- `404`: Error
- `409`: Error
- `422`: Error
- `429`: Error
- `500`: Error

---

[API](https://skmtc.dev/fuseai/apis/fuse-business-api.md) · [All operations](https://skmtc.dev/fuseai/apis/fuse-business-api/llms.txt) · [OpenAPI document](https://skmtc.dev/fuseai/apis/fuse-business-api/revisions/50d95e0536f4?raw)
