---
title: "Merge a duplicate into a canonical post"
method: POST
path: "/posts/{postId}/merge"
---

# Merge a duplicate into a canonical post

`POST /posts/{postId}/merge`

## Request

- Base URL: `https://app.voteship.app/api/v1`
- URL: `https://app.voteship.app/api/v1/posts/{postId}/merge`
- Auth: HTTP bearer

Same-project posts only. Votes and subscribers move with deduplication; seeded votes are preserved. Source becomes CLOSED, zero votes, mergedIntoPostId set, releaseId cleared. Comments and metadata remain on the source. Rejects self/cyclic merges and merged targets. Repeating a merge is safe. No email; post.merged webhooks and audit records still fire, including on retries.

## Path parameters

- `postId` string, required

## Request body

- object
  - `targetPostId` string, required

## Response `200`

Merge a duplicate into a canonical post

- object
  - `data` object
    - `source` Post
      - `id` string
      - `projectId` string
      - `title` string
      - `description` string, nullable
      - `status` 'PENDING' | 'APPROVED' | 'IN_PROGRESS' | 'COMPLETE' | 'CLOSED' | 'ARCHIVED'
      - `voteCount` integer
      - `metadata` object, nullable: Private context. Replaces the object; null clears it. Omitted from public responses; available to secret-key APIs and trusted admin webhooks.
      - `createdAt` string, date-time
      - `updatedAt` string, date-time
    - `target` Post
      - `id` string
      - `projectId` string
      - `title` string
      - `description` string, nullable
      - `status` 'PENDING' | 'APPROVED' | 'IN_PROGRESS' | 'COMPLETE' | 'CLOSED' | 'ARCHIVED'
      - `voteCount` integer
      - `metadata` object, nullable: Private context. Replaces the object; null clears it. Omitted from public responses; available to secret-key APIs and trusted admin webhooks.
      - `createdAt` string, date-time
      - `updatedAt` string, date-time
    - `movedVotes` integer

## Other responses

- `400`: Validation error
- `401`: Secret API key required
- `404`: Entity not found in this project
- `409`: Source or target already merged

---

[API](https://skmtc.dev/voteship/apis/voteship-api.md) · [All operations](https://skmtc.dev/voteship/apis/voteship-api/llms.txt) · [OpenAPI document](https://skmtc.dev/voteship/apis/voteship-api/revisions/51ab9e650f82?raw)
