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.

FieldTypeRequiredDescription
message_idUUIDyesTarget message.
emojistringyesThe reaction emoji, e.g. "šŸ‘".
removebooleannoPass 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 Reaction and broadcasts events.reactionAdded.
  • When toggled off or removed, returns { "ok": true } and broadcasts events.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.

FieldTypeRequiredDescription
chat_idUUIDyesConversation id.
actionstringyes"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).

FieldTypeRequiredDescription
chat_idUUIDyesConversation containing the component.
message_idUUIDyesThe message that rendered the component.
actionstringyesThe opaque action token from the button/form.
fieldsobjectnoSubmitted 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.

TokenEffect
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:limitPrompt 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.