Chats

Search archived chat messages by text content

Searches the Mongo archive (*_chat_archive.messages) populated by the ejabberd mod_track_message hook. This is a parallel store to the live MAM history — denormalized, indexed for $text + substring queries, and isolated from the live XMPP DB so search load never touches the chat runtime.

Two query modes:

  • substring (default): case-insensitive regex on body. Finds short queries like "h" inside "hello" — good for autocomplete-style flows. Special regex characters are escaped, so a query like "." matches a literal dot, not "any char".
  • fulltext: Mongo $text operator. Token-based; won't match substrings of a word, but very fast and supports sort=relevance with a score field on each item.

Visibility:

  • B2B server token: full access to every message in the target app.
  • User token: restricted to chats the caller can see. Groupchat membership is resolved via user_to_chats; private 1-1 access is derived from the canonical chatId (the caller's xmppUsername must be one of the two participants).

When the caller passes an explicit chatId they have no access to, the response is 403 CHAT_FORBIDDEN (not an empty list) so the client can distinguish "denied" from "no matches".

Note: the archive only stores messages whose chat / users are registered in the Ethora API. Ad-hoc XMPP rooms and synthetic test fixtures don't pollute the searchable set.

get/v2/apps/{appId}/messages/search

Request

  • Base URL: https://api.chat.ethora.com
  • URL: https://api.chat.ethora.com/v2/apps/{appId}/messages/search
  • Auth: one of:
    • HTTP bearer
    • HTTP bearer

Path parameters

appIdstring required

Target App ID. Must be an app the calling actor owns or has been delegated access to.

Query parameters

qstring required

Search query (1..500 chars). Always required.

mode'substring' | 'fulltext'

Search mode: text (default; substring match on message body) or semantic (vector search via the AI service, if enabled).

chatIdstring

Optional chat localpart (${appId}_${uuid}, no @conference.host). When provided, scopes search to one chat. For user tokens, returns 403 CHAT_FORBIDDEN if the caller has no access to it.

fromUserIdstring

Bare uuid (not xmppUsername) — filters by sender.

sincestring date-time

Lower bound (inclusive) on message.createdAt. ISO-8601 timestamp or Unix-epoch seconds.

untilstring date-time

Upper bound (exclusive) on message.createdAt. Same format as since.

sort'date' | 'relevance'

relevance is only meaningful with mode=fulltext; with substring it falls back to date desc.

limitinteger

Maximum number of items to return per page. Server caps vary per endpoint; the response carries the actual page size.

offsetinteger

Number of items to skip from the beginning of the result set. Use with limit for paging.

Response

{
  items: [
    {
      _id, appId, chatId, chatType, room,
      from, fromUserId, to, toUserId,
      body, messageId, stanzaId, createdAt,
      score?    // only when mode=fulltext AND sort=relevance
    }
  ],
  total: number,
  limit, offset, q, mode
}

Changes

No recorded changes to this operation across all 1 revision of this API.