Edit the content of a user message. All messages after the edited message are removed, and a fresh agent response is streamed back via SSE.
Only user messages can be edited. Attempting to edit an assistant message returns 400. The re-streamed response uses the same SSE event format as Send Message.
Editing is destructive. All messages following the edited message are permanently removed before the new response is streamed.
Bearer token obtained from the authenticate endpoint.
Set to text/event-stream to receive SSE responses.
Unique identifier of the chat containing the message.
Unique identifier of the user message to edit.
The new message content to replace the original.
ID of the database integration to query for the re-streamed response.
AI model to use for the re-streamed response. If omitted, the default model is used. See List Models for available values.
If true, internal tool events (tool_call, tool_result, tool_message) are included in the stream. Defaults to false.
Response
The response is a stream of Server-Sent Events — identical in format to Send Message.
Event types
| Event | Data | Description |
|---|
chat_metadata | {"id": "chat_...", "user_message_id": "msg_..."} | Emitted first. Contains the chat ID and the new user message ID. |
processing | {"status": "thinking"} | AI is processing the request. |
visualization | Full chart or table payload | A chart or table was generated. See Visualizations. |
message | {"content": "...", "id": "msg_..."} | The final response from the AI. |
error | {"error": "..."} | An error occurred during processing. |
curl -X PATCH "https://api.trellis.sh/v1/chats/chat_abc123/messages/msg_xyz789" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{
"content": "Show me the top 10 projects by budget instead",
"integration_id": "550e8400-e29b-41d4-a716-446655440000"
}'
import requests
import json
response = requests.patch(
"https://api.trellis.sh/v1/chats/chat_abc123/messages/msg_xyz789",
headers={
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
"Accept": "text/event-stream",
},
json={
"content": "Show me the top 10 projects by budget instead",
"integration_id": "550e8400-e29b-41d4-a716-446655440000",
},
stream=True
)
current_event = None
for line in response.iter_lines(decode_unicode=True):
if line.startswith("event: "):
current_event = line[7:]
elif line.startswith("data: ") and current_event:
data = json.loads(line[6:])
if current_event == "chat_metadata":
print("Chat:", data["id"], "| New message:", data["user_message_id"])
elif current_event == "message":
print(data["content"])
current_event = None
const response = await fetch(
"https://api.trellis.sh/v1/chats/chat_abc123/messages/msg_xyz789",
{
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
Accept: "text/event-stream",
},
body: JSON.stringify({
content: "Show me the top 10 projects by budget instead",
integration_id: "550e8400-e29b-41d4-a716-446655440000",
}),
}
);
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
let currentEvent = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop() || "";
for (const line of lines) {
if (line.startsWith("event: ")) {
currentEvent = line.slice(7);
} else if (line.startsWith("data: ") && currentEvent) {
const data = JSON.parse(line.slice(6));
if (currentEvent === "chat_metadata") {
console.log("Chat:", data.id, "| New message:", data.user_message_id);
} else if (currentEvent === "message") {
displayMessage(data.content);
}
currentEvent = "";
}
}
}
event: chat_metadata
data: {"id": "chat_abc123", "user_message_id": "msg_new001"}
event: processing
data: {"status": "thinking"}
event: processing
data: {"status": "analyzing"}
event: visualization
data: {"id": "ab12xy3456", "type": "chart", "chart_type": "bar", "title": "Top 10 Projects by Budget", "data": {"values": [{"label": "Green Spine Boulevard", "value": 31600000}, {"label": "Marina Gate Phase 2", "value": 22100000}], "x_axis_label": "Project", "y_axis_label": "Budget (AED)"}}
event: text_delta
data: {"content": "Here are the top 10 "}
event: text_delta
data: {"content": "projects by budget."}
event: message
data: {"content": "Here are the top 10 projects by budget.", "id": "msg_new002"}
{
"detail": "Can only edit user messages"
}
{
"detail": "Message not found"
}