Documentation

Message history and search

REST endpoints for reading chat transcripts, saving messages, and looking up history by user or chat.

The WebSocket gateway is the live channel; REST is the audit trail. Every message saved through the gateway is also addressable via /chat/* endpoints — useful for admin panels, exports, and offline rendering.

History by chat

GET/chat/history/{chatId}JWT

Returns every saved message for the conversation in chronological order. chatId formats:

  • customer:{email} — authenticated customer single-thread
  • customer:{sessionId}:{email} — guest customer scoped by session
  • {emailA}|{emailB} — staff-to-staff DM (sorted)
  • Anything provided by an agent when calling sendMessage directly
curl https://appengine.appmint.io/chat/history/customer:[email protected] \
  -H "orgid: my-org" -H "Authorization: Bearer <jwt>"

History by user

GET/chat/messages/{email}/{createdAfter?}JWT

All messages where the user appears as from or to. The optional createdAfter is an ISO timestamp for incremental sync.

FieldTypeDescription
email*string

The email address whose messages you want.

createdAfterstring

Only return messages created after this ISO timestamp. Useful for pagination.

Save a message

POST/chat/save/{chatId}JWT

Persist a message without going through the socket. Emits chat-new-message on the internal event bus, which downstream listeners (CRM inbox, automations) consume.

{
  "from": "[email protected]",
  "to": "[email protected]",
  "content": "Following up on our call.",
  "type": "user",
  "senderRole": "customer",
  "sentTime": 1714000000000
}

Update a message

PUT/chat/update/{chatId}JWT

Edit a previously saved message (typically status updates: sent → delivered → read). The body must include messageId. Emits chat-update-message.

{
  "messageId": "sk-abc",
  "status": "read",
  "readAt": "2026-04-25T12:34:56Z"
}

Live chat REST helper

POST/chat/live/{chatId}/{userId}JWT

Server-side send path used by integrations that don't hold a Socket.IO connection (cron jobs, webhook handlers, automation actions). Posts the message into the chat as if a live client had sent it.

File uploads

POST/chat/upload/{chatId}/{userId}No auth

Multipart upload — files[]. The endpoint is publicly callable so unauthenticated widget uploads work; the server checks the chat config before accepting. Returns an array of stored file references that you then pass to chat-message (or sendMessage) as the files field.

Send a transcript by email

POST/chat/transcript/sendJWT

Render the full conversation and email it. Used by widget "email me a copy" buttons.

{ "chatId": "customer:[email protected]", "email": "[email protected]" }

Get a single message

ChatService.getMessage(orgId, messageId) is also exposed internally and is what chat-update-message triggers. There's no dedicated GET /chat/message/:id REST endpoint at the time of writing — use /chat/history/{chatId} and filter client-side, or add the route if your admin needs single-message permalinks.

Active AI conversations

GET/chat/ai-activeJWT

Lists every conversation currently being handled by an AI assistant. The admin console uses this to show a "supervise AI" pane where agents can takeover-chat or assist-ai.

Searching messages

There is no dedicated full-text search endpoint in the chat module. For search, query the underlying chat_message collection through the data layer:

curl "https://appengine.appmint.io/data/chat_message?q=order+refund&limit=50" \
  -H "orgid: my-org" -H "Authorization: Bearer <jwt>"

The exact filter syntax is described in Data layer / queries.