# Duplicates

> The Duplicates page lists testimonials that are probably the same one twice, shows the copies side by side and merges them, with an undo.

The **Duplicates** page is a queue of testimonials that are probably the
same one twice, so you can keep one and clear the rest. Open
**Testimonials** in the site's sidebar, then **More** at the top of
[the Inbox](/docs/testimonials/inbox), then **Duplicates**. The menu
shows how many groups are open. The address is
`/sites/<site id>/testimonials/duplicates`.

Finding and merging duplicates is on every plan. Merging needs
`content.write`.

## The top of the page

| Control | What it does |
|---|---|
| **Merge all N exact matches** | Merges every exact group in one action. The button carries the number ("Merge all 4 exact matches", or "Merge the 1 exact match"). Shown while exact groups are in the queue. See below |
| **Confidence** | **All**, **Exact** or **Likely** |
| **Reason** | **Any reason**, or one of the four reasons in the next table |

The number of groups that match is at the right of that row.

## How a group forms

A testimonial is checked when it arrives, and a sweep runs every night
for what arrival could not see: two imports of one review, an edit that
made two texts alike, two people merged into one.

| Reason on the page | `reason` | Test | Confidence |
|---|---|---|---|
| Same review twice | `same_review` | Two testimonials carry the same id from their source and the same words, whoever each is filed under | Exact |
| Same person, same words | `same_words` | The same person, and the same words once capitals, spacing and punctuation are ignored | Exact |
| Same person, similar words | `near_words` | The same person, and words at least 85% alike | Likely |
| Same words, two people | `same_words_other_person` | The same words of 80 characters or more under two different people | Likely |

"The same person" is one person record, or two records with the same
name.

An exact repeat is usually stopped before it is stored: the same source
id, or the same person saying the same words, returns the testimonial
that is already there.

## A group

Each card is one group. Its header says the confidence, the reason in
words and the number of copies. The copies sit side by side.

| On each copy | What it shows |
|---|---|
| **Keep this one** | Picks the copy that stays. One is preselected and marked **Suggested**: the one in use, then the approved one, then the verified one, then the oldest |
| The person | With the verified mark when it has one |
| The facts | Status, rating, source, date received, how many places use it, and its recording or images |
| The words | With what differs from the other copy marked. "No words, only a recording." when there are none |
| The tags | As chips |
| **Open** | Opens that testimonial's page |

Under the copies are two buttons.

| Button | What it does |
|---|---|
| **Merge** | Merges the group into the copy you kept |
| **Not duplicates** | Closes the group and merges nothing. Those testimonials are never put together in the queue again |

## What a merge does

- The copy you keep keeps its own words, its status and its verified
  mark.
- It gains the tags, the places in manual collections, the widget and wall
  placements and the custom properties it lacks.
- The other copies go to the [trash](/docs/testimonials/trash), marked as
  merged. Restoring one from the trash undoes the merge for that copy.
- A merged copy that arrived this month stops counting toward the
  [monthly limit](/docs/testimonials/limits).

After a merge you are back on the queue with a notice that offers
**Undo**.

## Merge every exact match

The **Merge all N exact matches** button asks once, then merges each exact group into
the copy the order above picks. It is one action with one undo. One press
merges up to 100 groups. With more, press it again for the rest.

## Undo

A merge can be undone for 7 days from the
[undo list](/docs/testimonials/bulk-actions#the-undo-list). The copies
leave the trash as they were and count again, the group returns to the
queue, and the copy that was kept loses what the merge gave it. A copy
that was restored or deleted for good in the meantime is left alone.

## API and MCP

| Action | MCP tool | Permission |
|---|---|---|
| List the queue | `testimonial_duplicates_list` | `analytics.read` |
| Merge a group | `testimonials_merge` | `content.write` |
| Not duplicates | `testimonial_duplicates_dismiss` | `content.write` |
| Merge every exact match | `testimonial_duplicates_merge_exact` | `content.write` |

The inputs are in the [API reference](/docs/api) and the
[MCP reference](/docs/mcp). What is worth knowing beside them:

- For `testimonials_merge` the keeper is the testimonial in the path and
  `duplicate_ids` names 1 to 20 copies. `body_from` names a copy whose
  words the keeper takes instead of its own, and that change is kept in
  its history. The response carries `meta.undo_id`.
- `testimonial_duplicates_dismiss` takes `testimonial_ids`: every copy of
  one open group.
- Call `testimonial_duplicates_merge_exact` with `dry_run` first. It
  responds with `total`, the number of exact groups, and `changed`, the
  number of copies that would go to the trash. Then send `confirm_count`
  with that total. If the number has changed, nothing is merged and the
  error is `count_changed` with the new number in `error.count`.
- `testimonial_duplicates_list` takes `confidence` (`exact` or `likely`)
  and `reason`.

Ask your assistant:

- "Are there duplicate testimonials? Merge the exact ones and show me the
  rest."
- "Merge these two reviews from Thijs and keep the longer text."
- "These two are from different customers. Mark them as not duplicates."

## Good to know

- A testimonial in an open group carries the **Possible duplicate**
  badge. Its own page lists the other copies with **Review duplicates**,
  and `is:duplicate` in the search box finds them all.
- A group stays in the queue while at least two of its copies are out of
  the trash. Moving one of two copies to the trash takes the group off
  the page.
- The nightly sweep covers the sites that received something in the last
  two days, and every site once a week. A pair made by an edit can
  therefore take until the next night to appear.
- A testimonial with no words, such as a video without a caption, is not
  compared.
- To split a group of three, merge the two that are the same first, then
  mark what is left as not duplicates.
