Send a message to the assistant
Stores the member’s message, generates the reply with the company’s assistant and returns both. One reply runs per conversation, and at most 10 replies run at once for a member. The first message names an untitled conversation. Send Accept: text/event-stream to receive the reply as it is written, as the company’s admin chat streams it: data: frames of JSON, {"delta": "<text>"} for each part of the reply, then {"exchange": {...}} with the stored messages (the same object as the data of the 201), then data: END_OF_STREAM. A failure after the stream has opened arrives as {"error": "<message>", "status": <status>} before the end; one found before it opens (a conflict, a billing refusal, a limit) is the JSON error below. A client that prefers application/json, or sends no Accept, gets the completed exchange instead. Stopping the reply, with the stop operation or by closing the connection, ends the stream with the reply stored as stopped. Limited to 20 messages per minute per credential, past which the rate limiter answers 429 with its own body rather than the error envelope; replies use the company’s AI billing, which can refuse with 402 or 429 in the error envelope.
curl --request POST \
--url https://api.fluid.app/api/member/v2026-10/ai/conversations/{id}/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"text": "Draft a follow-up for Sam, who asked about the starter kit"
}
'import requests
url = "https://api.fluid.app/api/member/v2026-10/ai/conversations/{id}/messages"
payload = { "text": "Draft a follow-up for Sam, who asked about the starter kit" }
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({text: 'Draft a follow-up for Sam, who asked about the starter kit'})
};
fetch('https://api.fluid.app/api/member/v2026-10/ai/conversations/{id}/messages', 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/ai/conversations/{id}/messages",
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([
'text' => 'Draft a follow-up for Sam, who asked about the starter kit'
]),
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/ai/conversations/{id}/messages"
payload := strings.NewReader("{\n \"text\": \"Draft a follow-up for Sam, who asked about the starter kit\"\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/member/v2026-10/ai/conversations/{id}/messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"text\": \"Draft a follow-up for Sam, who asked about the starter kit\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/member/v2026-10/ai/conversations/{id}/messages")
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 \"text\": \"Draft a follow-up for Sam, who asked about the starter kit\"\n}"
response = http.request(request)
puts response.read_bodydata: {"delta":"Hi Sam, "}
data: {"delta":"thanks for asking about the starter kit."}
data: {"exchange":{"user_message":{"id":"01a0f512-2c1e-7b11-9a3d-4f0e8d1c2b10","conversation_id":"01a0f512-1a00-7c22-8b11-5e3f2a1d0c01","role":"user","text":"Draft a follow-up for Sam","tool_calls":[],"status":null,"feedback":null,"created_at":"2026-10-01T15:01:00.104000Z"},"assistant_message":{"id":"01a0f512-2c40-7d55-a1b2-0c9e8f7a6b54","conversation_id":"01a0f512-1a00-7c22-8b11-5e3f2a1d0c01","role":"assistant","text":"Hi Sam, thanks for asking about the starter kit.","tool_calls":[],"status":"completed","feedback":null,"created_at":"2026-10-01T15:01:04.512000Z"}}}
data: END_OF_STREAM
{
"status": 201,
"data": {
"user_message": {
"id": "01a0f512-2c1e-7b11-9a3d-4f0e8d1c2b10",
"conversation_id": "01a0f512-1a00-7c22-8b11-5e3f2a1d0c01",
"role": "user",
"text": "Draft a follow-up for Sam, who asked about the starter kit",
"tool_calls": [],
"status": null,
"feedback": null,
"created_at": "2026-10-01T15:01:00.104000Z"
},
"assistant_message": {
"id": "01a0f512-2c40-7d55-a1b2-0c9e8f7a6b54",
"conversation_id": "01a0f512-1a00-7c22-8b11-5e3f2a1d0c01",
"role": "assistant",
"text": "Hi Sam, thanks for asking about the starter kit. Would a quick call on Thursday work?",
"tool_calls": [],
"status": "completed",
"feedback": null,
"created_at": "2026-10-01T15:01:04.512000Z"
}
},
"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"
}
}{
"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
Conversation id.
Body
The member's message.
The message; must contain a non-space character.
1 - 8000Response
The reply as server-sent events, sent when Accept prefers text/event-stream. The status is 200 because it is sent before the reply is complete; the reply's outcome is in the final frames.
Frames separated by a blank line. Each starts with data: and holds one JSON object (delta, exchange or error), except the last, END_OF_STREAM.
curl --request POST \
--url https://api.fluid.app/api/member/v2026-10/ai/conversations/{id}/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"text": "Draft a follow-up for Sam, who asked about the starter kit"
}
'import requests
url = "https://api.fluid.app/api/member/v2026-10/ai/conversations/{id}/messages"
payload = { "text": "Draft a follow-up for Sam, who asked about the starter kit" }
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({text: 'Draft a follow-up for Sam, who asked about the starter kit'})
};
fetch('https://api.fluid.app/api/member/v2026-10/ai/conversations/{id}/messages', 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/ai/conversations/{id}/messages",
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([
'text' => 'Draft a follow-up for Sam, who asked about the starter kit'
]),
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/ai/conversations/{id}/messages"
payload := strings.NewReader("{\n \"text\": \"Draft a follow-up for Sam, who asked about the starter kit\"\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/member/v2026-10/ai/conversations/{id}/messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"text\": \"Draft a follow-up for Sam, who asked about the starter kit\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/member/v2026-10/ai/conversations/{id}/messages")
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 \"text\": \"Draft a follow-up for Sam, who asked about the starter kit\"\n}"
response = http.request(request)
puts response.read_bodydata: {"delta":"Hi Sam, "}
data: {"delta":"thanks for asking about the starter kit."}
data: {"exchange":{"user_message":{"id":"01a0f512-2c1e-7b11-9a3d-4f0e8d1c2b10","conversation_id":"01a0f512-1a00-7c22-8b11-5e3f2a1d0c01","role":"user","text":"Draft a follow-up for Sam","tool_calls":[],"status":null,"feedback":null,"created_at":"2026-10-01T15:01:00.104000Z"},"assistant_message":{"id":"01a0f512-2c40-7d55-a1b2-0c9e8f7a6b54","conversation_id":"01a0f512-1a00-7c22-8b11-5e3f2a1d0c01","role":"assistant","text":"Hi Sam, thanks for asking about the starter kit.","tool_calls":[],"status":"completed","feedback":null,"created_at":"2026-10-01T15:01:04.512000Z"}}}
data: END_OF_STREAM
{
"status": 201,
"data": {
"user_message": {
"id": "01a0f512-2c1e-7b11-9a3d-4f0e8d1c2b10",
"conversation_id": "01a0f512-1a00-7c22-8b11-5e3f2a1d0c01",
"role": "user",
"text": "Draft a follow-up for Sam, who asked about the starter kit",
"tool_calls": [],
"status": null,
"feedback": null,
"created_at": "2026-10-01T15:01:00.104000Z"
},
"assistant_message": {
"id": "01a0f512-2c40-7d55-a1b2-0c9e8f7a6b54",
"conversation_id": "01a0f512-1a00-7c22-8b11-5e3f2a1d0c01",
"role": "assistant",
"text": "Hi Sam, thanks for asking about the starter kit. Would a quick call on Thursday work?",
"tool_calls": [],
"status": "completed",
"feedback": null,
"created_at": "2026-10-01T15:01:04.512000Z"
}
},
"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"
}
}{
"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"
}
}