Merge a ticket into the older one Mist read it as a repeat of
Requires a user session with multiplayer_tasks.update or the existing application_themes.update permission, and Cowork enabled for the company (features/cowork, Phase 026). Mist suggests (mist_confidence.duplicate_of) and never merges; this is the person’s decision. The ticket’s request is appended to the older ticket’s request under a heading “Merged from ”, through the same edit as rewriting the request, so the older ticket is scored again; and the ticket is closed (status skipped) and frozen, keeping its row, history and links, until it is split. Both changes are made together or not at all. The older ticket has no version to send: it is read under its lock. Only the suggestion of the ticket’s current read can be merged, while the work has not started. Work sent to an agency, and an older ticket Mist holds, that is in Review, or that carries a run’s result, cannot take a request. Work in another company, deleted work, an unknown id, and a company without Cowork all answer the same not-found.
curl --request POST \
--url https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"expected_version": 3
}
'import requests
url = "https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge"
payload = { "expected_version": 3 }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({expected_version: 3})
};
fetch('https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'expected_version' => 3
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge"
payload := strings.NewReader("{\n \"expected_version\": 3\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"expected_version\": 3\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"expected_version\": 3\n}"
response = http.request(request)
puts response.read_body{
"task": {
"id": "01a1d0e3-7ee5-7686-8b23-d4323dafb2bf",
"agency": null,
"agency_join_request": null,
"agency_request": null,
"assignee": null,
"assigner": null,
"board_position": null,
"board_position_at_ms": null,
"category": null,
"client_id": "dup-fdd2e9feb0fc",
"company_id": 96778814,
"conversation_id": null,
"created_at": "2026-11-09T17:52:12Z",
"creator_id": 433400890,
"description": "Place order does nothing on iOS\n\nMerged from Cannot tap pay on my phone\n\nPay button dead on my phone",
"due_on": null,
"kind": null,
"lock_version": 1,
"merged_from": [
{
"id": "01a1d0e3-7ee8-7e86-b25e-40ee6aa70b2b",
"title": "Cannot tap pay on my phone",
"merged_at": "2026-11-12T17:52:12.598Z",
"version": 1
}
],
"merged_into": null,
"mist_confidence": {
"state": "assessing"
},
"plan": null,
"priority": null,
"run_id": null,
"run_thread_id": null,
"source_threads": [],
"status": "open",
"status_editable": true,
"tags": [],
"title": "Place order button does nothing on iPhone",
"updated_at": "2026-11-12T17:52:12Z"
},
"merged_task": {
"id": "01a1d0e3-7ee8-7e86-b25e-40ee6aa70b2b",
"agency": null,
"agency_join_request": null,
"agency_request": null,
"assignee": null,
"assigner": null,
"board_position": null,
"board_position_at_ms": null,
"category": null,
"client_id": "dup-218265691374",
"company_id": 96778814,
"conversation_id": null,
"created_at": "2026-11-12T16:52:12Z",
"creator_id": 433400890,
"description": "Pay button dead on my phone",
"due_on": null,
"kind": null,
"lock_version": 1,
"merged_from": [],
"merged_into": {
"id": "01a1d0e3-7ee5-7686-8b23-d4323dafb2bf",
"title": "Place order button does nothing on iPhone",
"deleted": false
},
"mist_confidence": {
"state": "current",
"assessment_id": "01a1d0e3-7eeb-7d3d-9d51-275071925d26",
"score": 4,
"band": "green",
"summary": "A clear change.",
"concerns": [
"Detail"
],
"raise_by": [],
"assessed_at": "2026-11-12T17:52:12.521Z",
"suggested_kind": "change",
"category": "eng",
"difficulty": "easy",
"hours_low": 1,
"hours_high": 2,
"questions": []
},
"plan": null,
"priority": null,
"run_id": null,
"run_thread_id": null,
"source_threads": [],
"status": "skipped",
"status_editable": true,
"tags": [],
"title": "Cannot tap pay on my phone",
"updated_at": "2026-11-12T17:52:12Z"
},
"status": 200,
"meta": {
"request_uuid": null,
"timestamp": "2026-11-12T17:52:12Z"
}
}{
"error": {
"message": "<string>",
"details": {}
},
"status": 123,
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"error": {
"message": "<string>",
"details": {}
},
"status": 123,
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"error": {
"message": "<string>",
"details": {}
},
"status": 123,
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
The task UUID of the ticket to merge.
The read that named the older ticket, from mist_confidence.assessment_id.
Body
The ticket's lock_version the person observed.
x >= 0Response
The older ticket, now carrying the block, and the ticket that was closed.
curl --request POST \
--url https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"expected_version": 3
}
'import requests
url = "https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge"
payload = { "expected_version": 3 }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({expected_version: 3})
};
fetch('https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'expected_version' => 3
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge"
payload := strings.NewReader("{\n \"expected_version\": 3\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"expected_version\": 3\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/v202604/multiplayer/tasks/{id}/assessments/{assessment_id}/merge")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"expected_version\": 3\n}"
response = http.request(request)
puts response.read_body{
"task": {
"id": "01a1d0e3-7ee5-7686-8b23-d4323dafb2bf",
"agency": null,
"agency_join_request": null,
"agency_request": null,
"assignee": null,
"assigner": null,
"board_position": null,
"board_position_at_ms": null,
"category": null,
"client_id": "dup-fdd2e9feb0fc",
"company_id": 96778814,
"conversation_id": null,
"created_at": "2026-11-09T17:52:12Z",
"creator_id": 433400890,
"description": "Place order does nothing on iOS\n\nMerged from Cannot tap pay on my phone\n\nPay button dead on my phone",
"due_on": null,
"kind": null,
"lock_version": 1,
"merged_from": [
{
"id": "01a1d0e3-7ee8-7e86-b25e-40ee6aa70b2b",
"title": "Cannot tap pay on my phone",
"merged_at": "2026-11-12T17:52:12.598Z",
"version": 1
}
],
"merged_into": null,
"mist_confidence": {
"state": "assessing"
},
"plan": null,
"priority": null,
"run_id": null,
"run_thread_id": null,
"source_threads": [],
"status": "open",
"status_editable": true,
"tags": [],
"title": "Place order button does nothing on iPhone",
"updated_at": "2026-11-12T17:52:12Z"
},
"merged_task": {
"id": "01a1d0e3-7ee8-7e86-b25e-40ee6aa70b2b",
"agency": null,
"agency_join_request": null,
"agency_request": null,
"assignee": null,
"assigner": null,
"board_position": null,
"board_position_at_ms": null,
"category": null,
"client_id": "dup-218265691374",
"company_id": 96778814,
"conversation_id": null,
"created_at": "2026-11-12T16:52:12Z",
"creator_id": 433400890,
"description": "Pay button dead on my phone",
"due_on": null,
"kind": null,
"lock_version": 1,
"merged_from": [],
"merged_into": {
"id": "01a1d0e3-7ee5-7686-8b23-d4323dafb2bf",
"title": "Place order button does nothing on iPhone",
"deleted": false
},
"mist_confidence": {
"state": "current",
"assessment_id": "01a1d0e3-7eeb-7d3d-9d51-275071925d26",
"score": 4,
"band": "green",
"summary": "A clear change.",
"concerns": [
"Detail"
],
"raise_by": [],
"assessed_at": "2026-11-12T17:52:12.521Z",
"suggested_kind": "change",
"category": "eng",
"difficulty": "easy",
"hours_low": 1,
"hours_high": 2,
"questions": []
},
"plan": null,
"priority": null,
"run_id": null,
"run_thread_id": null,
"source_threads": [],
"status": "skipped",
"status_editable": true,
"tags": [],
"title": "Cannot tap pay on my phone",
"updated_at": "2026-11-12T17:52:12Z"
},
"status": 200,
"meta": {
"request_uuid": null,
"timestamp": "2026-11-12T17:52:12Z"
}
}{
"error": {
"message": "<string>",
"details": {}
},
"status": 123,
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"error": {
"message": "<string>",
"details": {}
},
"status": 123,
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"error": {
"message": "<string>",
"details": {}
},
"status": 123,
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}