Merge feedback posts
Combine two duplicate posts into one. Votes and comments on the source post move to the target.
Merges one feedback post into another. Use this when two posts cover the same idea and should be combined.
After a successful merge:
- The source post (
merge_post_id) is marked as merged into the target. - Votes on the source are reattributed to the target.
- Comments on the source remain attached to the source for audit, but the merged status is exposed in the dashboard so end-users see "merged into …".
- Both posts must belong to the same organization.
Endpoint
POST https://api.productbridge.io/api/external/v1/feedback-posts/merge
Arguments
Your organization's public API key. See Authentication.
UUID of the source post being merged (the duplicate).
UUID of the target post the source is being merged into (the canonical version).
UUID of the user performing the merge. Recorded for audit.
merge_post_id must differ from into_post_id. Passing the same UUID twice returns a 422 validation error.
Returns
{ "success": true }
Example request
curl -X POST https://api.productbridge.io/api/external/v1/feedback-posts/merge \
-H 'Content-Type: application/json' \
-d '{
"api_key": "pb_YOUR_PUBLIC_API_KEY",
"merge_post_id": "dd3c3ef8-b8cd-cd15-01ba-duplicate001",
"into_post_id": "aa3c3ef8-b8cd-cd15-01ba-postpost0001",
"merger_id": "cc3c3ef8-b8cd-cd15-01ba-adminuser001"
}'
const res = await fetch(
"https://api.productbridge.io/api/external/v1/feedback-posts/merge",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
api_key: process.env.PRODUCTBRIDGE_API_KEY,
merge_post_id: "dd3c3ef8-b8cd-cd15-01ba-duplicate001",
into_post_id: "aa3c3ef8-b8cd-cd15-01ba-postpost0001",
merger_id: "cc3c3ef8-b8cd-cd15-01ba-adminuser001",
}),
}
);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
import os, httpx
resp = httpx.post(
"https://api.productbridge.io/api/external/v1/feedback-posts/merge",
json={
"api_key": os.environ["PRODUCTBRIDGE_API_KEY"],
"merge_post_id": "dd3c3ef8-b8cd-cd15-01ba-duplicate001",
"into_post_id": "aa3c3ef8-b8cd-cd15-01ba-postpost0001",
"merger_id": "cc3c3ef8-b8cd-cd15-01ba-adminuser001",
},
)
resp.raise_for_status()
Example response
{ "success": true }
Errors
| Status | Body | Cause |
|---|---|---|
401 | {"detail":{"error":"invalid api_key"}} | Missing / unknown / inactive api_key. |
400 | {"detail": "Cannot merge posts. Ensure both posts exist, are active, and neither is already merged."} | The merge could not be performed — e.g. one of the posts is inactive or already merged. Note: detail is a plain string here, not the usual {"error": ...} object. |
404 | {"detail":{"error":"merge_post not found"}} or {"detail":{"error":"into_post not found"}} | Either id doesn't exist, has been deleted, or belongs to another organization. |
422 | Validation error envelope | merge_post_id equals into_post_id, or required fields missing. |
See Errors for the full envelope shape.