Save a draft
Saves the member’s own unsent draft in the conversation without sending it. Only the fields sent change. A submission with no text, no subject, no reply and no attachments removes the whole draft and answers an empty object. A request with no body is refused rather than read as an empty submission, so only an explicit empty JSON object clears the draft. Attachments sent are added to those already saved, and a draft that has attachments needs no text. A file already on the draft with the same URL and filename is not added again, and a save that would leave the draft with more than 10 attachments is refused with 422.
curl --request PUT \
--url https://api.fluid.app/api/member/v2026-10/messaging/conversations/{id}/draft \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"text": "Running ten minutes late.",
"subject": "Kickoff"
}
'import requests
url = "https://api.fluid.app/api/member/v2026-10/messaging/conversations/{id}/draft"
payload = {
"text": "Running ten minutes late.",
"subject": "Kickoff"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({text: 'Running ten minutes late.', subject: 'Kickoff'})
};
fetch('https://api.fluid.app/api/member/v2026-10/messaging/conversations/{id}/draft', 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/member/v2026-10/messaging/conversations/{id}/draft",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'text' => 'Running ten minutes late.',
'subject' => 'Kickoff'
]),
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/member/v2026-10/messaging/conversations/{id}/draft"
payload := strings.NewReader("{\n \"text\": \"Running ten minutes late.\",\n \"subject\": \"Kickoff\"\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.fluid.app/api/member/v2026-10/messaging/conversations/{id}/draft")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"text\": \"Running ten minutes late.\",\n \"subject\": \"Kickoff\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/member/v2026-10/messaging/conversations/{id}/draft")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"text\": \"Running ten minutes late.\",\n \"subject\": \"Kickoff\"\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"data": {
"id": "0199a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a70",
"conversation_id": "0199a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b",
"text": "Running ten minutes late.",
"subject": "Kickoff",
"attachments": [],
"reply_to": null,
"mentioned_recipients": [],
"created_at": "2026-10-01T15:01:59Z",
"updated_at": "2026-10-01T15:01:59Z"
},
"meta": {
"request_uuid": "01a0f4fe-de00-75b3-8d8a-b74b0cde8b07",
"timestamp": "2026-10-01T15:04:05Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}Authorizations
A member credential in the Authorization: Bearer header: a member
session JWT, a portal JWT whose login is linked to a membership in
that company, or a member token. The credential alone
identifies the member and company.
Path Parameters
Public id of a conversation the member can see.
Body
10000255A message in this conversation the member can read; null removes the reply.
Files the client has uploaded, named by URL, as the legacy composer takes them. They are added to the draft's saved attachments, which hold at most 10 in all. The URL is not checked as an owned upload.
10Show child attributes
Show child attributes
Response
The saved draft, or an empty object when a blank save cleared it.
The saved draft, or an empty object after a blank save cleared it.
curl --request PUT \
--url https://api.fluid.app/api/member/v2026-10/messaging/conversations/{id}/draft \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"text": "Running ten minutes late.",
"subject": "Kickoff"
}
'import requests
url = "https://api.fluid.app/api/member/v2026-10/messaging/conversations/{id}/draft"
payload = {
"text": "Running ten minutes late.",
"subject": "Kickoff"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({text: 'Running ten minutes late.', subject: 'Kickoff'})
};
fetch('https://api.fluid.app/api/member/v2026-10/messaging/conversations/{id}/draft', 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/member/v2026-10/messaging/conversations/{id}/draft",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'text' => 'Running ten minutes late.',
'subject' => 'Kickoff'
]),
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/member/v2026-10/messaging/conversations/{id}/draft"
payload := strings.NewReader("{\n \"text\": \"Running ten minutes late.\",\n \"subject\": \"Kickoff\"\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.fluid.app/api/member/v2026-10/messaging/conversations/{id}/draft")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"text\": \"Running ten minutes late.\",\n \"subject\": \"Kickoff\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/member/v2026-10/messaging/conversations/{id}/draft")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"text\": \"Running ten minutes late.\",\n \"subject\": \"Kickoff\"\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"data": {
"id": "0199a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a70",
"conversation_id": "0199a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b",
"text": "Running ten minutes late.",
"subject": "Kickoff",
"attachments": [],
"reply_to": null,
"mentioned_recipients": [],
"created_at": "2026-10-01T15:01:59Z",
"updated_at": "2026-10-01T15:01:59Z"
},
"meta": {
"request_uuid": "01a0f4fe-de00-75b3-8d8a-b74b0cde8b07",
"timestamp": "2026-10-01T15:04:05Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}