Reactions & actions#
All endpoints require authentication.
POST /api/setMessageReaction#
Add or remove an emoji reaction on a message. Adding the same emoji you already reacted with toggles it off.
| Field | Type | Required | Description |
|---|---|---|---|
message_id | UUID | yes | Target message. |
emoji | string | yes | The reaction emoji, e.g. "š". |
remove | boolean | no | Pass true to explicitly remove instead of add. Default false. |
curl -X POST http://localhost:4000/api/setMessageReaction \
-H "authorization: Bearer dev:ops" \
-H "content-type: application/json" \
-d '{ "message_id": "a1ā¦", "emoji": "š„" }'Response#
- When a reaction is added, returns the new
Reactionand broadcastsevents.reactionAdded. - When toggled off or removed, returns
{ "ok": true }and broadcastsevents.reactionRemoved.
{
"ok": true,
"result": {
"message_id": "a1ā¦",
"reactor": { "username": "ops", "kind": "human", "display_name": "Ops" },
"emoji": "š„",
"created_at": "2026-06-06T16:21:00Z"
}
}Errors ā 404 if the message doesn't exist.
POST /api/sendChatAction#
Advertise (or clear) a typing indicator to the other participants.
| Field | Type | Required | Description |
|---|---|---|---|
chat_id | UUID | yes | Conversation id. |
action | string | yes | "typing" sets the indicator; any other value (e.g. "cancel") clears it. |
curl -X POST http://localhost:4000/api/sendChatAction \
-H "authorization: Bearer dev:ops" \
-H "content-type: application/json" \
-d '{ "chat_id": "0d6cā¦", "action": "typing" }'Returns { "ok": true } and broadcasts events.typing to everyone except the sender.
POST /api/sendComponentAction#
Submit an interactive Markdoc component action ā a button press or a form submission. The opaque action token is interpreted server-side; for recognized tokens, the authoring agent posts a confirmation message back into the room (as a new events.messageNew).
| Field | Type | Required | Description |
|---|---|---|---|
chat_id | UUID | yes | Conversation containing the component. |
message_id | UUID | yes | The message that rendered the component. |
action | string | yes | The opaque action token from the button/form. |
fields | object | no | Submitted form values, when the component is a form. |
curl -X POST http://localhost:4000/api/sendComponentAction \
-H "authorization: Bearer dev:ops" \
-H "content-type: application/json" \
-d '{ "chat_id": "0d6cā¦", "message_id": "a1ā¦", "action": "trade:buy:AAPL:100" }'Returns { "ok": true }.
Recognized action tokens#
The demo server pattern-matches a few prefixes and replies with a Markdoc confirmation; everything else echoes a generic acknowledgement.
| Token | Effect |
|---|---|
trade:buy:<sym>:<qty> | "Buy order placed" card |
trade:sell:<sym>:<qty> | "Sell order placed" card |
alert:<sym>:<gt|lt>:<val> | "Alert set" confirmation |
modify:limit | Prompt to send a limit price |
form_submit:<id> | "Form submitted" card |
cancel:* / dismiss:* | Silently swallowed (no reply) |
Errors ā 404 if the conversation is missing; 403 if you're not a participant.
Where actions will go
Today the server interprets a fixed set of tokens. Long-term these route into the authoring agent's tool-call surface or a server builtin ā see Shared content.