> ## Documentation Index
> Fetch the complete documentation index at: https://learn.social.plus/llms.txt
> Use this file to discover all available pages before exploring further.

# Search Channels & Messages

> Full-text search across chat channels and messages by keyword, with filters for type, membership, sender, tags, and content type.

Give users a way to find the conversation or the exact message they remember. Channel search helps a member locate a community, live room, or conversation by name, while message search reaches into message content across channels so users can jump straight to a receipt, an address, or a decision buried in the history. Both surfaces accept a keyword plus filters, so you can scope results to what the current user is allowed to see and to the kind of content they are looking for.

## Platform Surface

| Capability      | TypeScript                              | iOS                        | Android                         | Flutter                                          |
| --------------- | --------------------------------------- | -------------------------- | ------------------------------- | ------------------------------------------------ |
| Search channels | `ChannelRepository.searchChannels(...)` | `searchChannels(options:)` | `searchChannels()` builder      | `searchChannels()` builder                       |
| Search messages | `MessageRepository.searchMessage(...)`  | `searchMessages(options:)` | `searchMessages(query)` builder | `newMessageRepository().searchMessage()` builder |

## Parameters

Both searches share a common core. `query` is the keyword to match; the remaining fields narrow the result set. Not every parameter applies to both searches — the scope column notes where each one is used.

| Parameter                     | Scope              | Required                                                 | Platforms                                               | Description                                                                                                                                                                    |
| ----------------------------- | ------------------ | -------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `query`                       | Channels, Messages | Required for message search; optional for channel search | TypeScript, iOS, Android, Flutter                       | Keyword to search for.                                                                                                                                                         |
| `exactMatch`                  | Channels, Messages | No                                                       | TypeScript, iOS, Android, Flutter                       | When `true`, match the keyword exactly rather than as a partial/fuzzy match. Defaults to `false`.                                                                              |
| `types`                       | Channels, Messages | No                                                       | TypeScript, iOS, Android, Flutter                       | For channels, restrict to channel types (community, live, conversation, broadcast). For messages, restrict to message content types (text, image, file, video, audio, custom). |
| `isMemberOnly` / `memberOnly` | Channels           | No                                                       | iOS, Android, Flutter                                   | Limit channel results to channels the current user is a member of.                                                                                                             |
| `tags`                        | Channels, Messages | No                                                       | TypeScript, iOS, Android, Flutter                       | Include only results carrying the given app-defined tags.                                                                                                                      |
| `channelId`                   | Messages           | No                                                       | TypeScript, iOS, Android, Flutter                       | Scope message results to a single channel.                                                                                                                                     |
| `messageFeedId`               | Messages           | No                                                       | TypeScript, iOS, Android, Flutter                       | Scope message results to a single message feed (sub-channel).                                                                                                                  |
| `userIds`                     | Messages           | No                                                       | TypeScript, iOS, Android, Flutter                       | Restrict message results to messages sent by the given users.                                                                                                                  |
| `sortBy`                      | Channels, Messages | No                                                       | TypeScript, iOS, Android, Flutter                       | Sort field. Channels: `relevance` or `lastActivity`. Messages: `relevance` or `createdAt`. Defaults to `relevance`.                                                            |
| `orderBy`                     | Channels, Messages | No                                                       | TypeScript, iOS, Android, Flutter                       | Result order. `asc` or `desc` on TypeScript, Android, and Flutter; on iOS use the `AmitySearchOrderBy` cases `.ascending` / `.descending`.                                     |
| `limit`                       | Channels, Messages | No                                                       | TypeScript, iOS (channel search only), Android, Flutter | Page size. On iOS, only `AmityChannelSearchOptions` takes a `limit`; message search returns an `AmityCollection` that you page with `nextPage()` instead.                      |

## Search Channels

Search channels by keyword, then narrow by type, membership, and tags.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { ChannelRepository } from '@amityco/ts-sdk';

  const unsubscribe = ChannelRepository.searchChannels(
    { query: 'support' },
    ({ data: channels, onNextPage, hasNextPage, loading, error }) => {
      if (error) handleError(error);

      if (!loading && channels) {
        renderResults(channels);
      }

      if (hasNextPage) onNextPage?.();
    },
  );

  unsubscribe();
  ```

  ```swift iOS theme={null}
  let options = AmityChannelSearchOptions()
  options.query = "support"
  options.types = ["community", "live"]
  options.isMemberOnly = true
  options.tags = ["vip"]
  options.sortBy = .relevance

  let channels = channelRepository.searchChannels(options: options)
  token = channels.observe { collection, error in
      if let error {
          handleError(error)
          return
      }

      showSuccessMessage(collection.snapshots.count)
  }
  ```

  ```kotlin Android theme={null}
  val disposable = channelRepository
      .searchChannels()
      .withQuery("support")
      .types(listOf(AmityChannel.Type.COMMUNITY, AmityChannel.Type.LIVE))
      .memberOnly(true)
      .tags(listOf("vip"))
      .sortBy("relevance")
      .build()
      .query()
      .subscribe(
          { channels -> showSuccessMessage(channels) },
          { error -> handleGeneralError(error) },
      )
  ```

  ```dart Flutter theme={null}
  final liveCollection = AmityChatClient.newChannelRepository()
      .searchChannels()
      .withQuery('support')
      .types([AmityChannelType.COMMUNITY, AmityChannelType.LIVE])
      .memberOnly(true)
      .tags(['vip'])
      .sortBy('relevance')
      .getLiveCollection();

  liveCollection.getStreamController().stream.listen((channels) {
    final count = channels.length;
  });

  await liveCollection.loadNext();
  ```
</CodeGroup>

## Search Messages

Search message content across channels, then narrow by channel, sender, tags, and content type. `query` is required on every platform.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { MessageRepository } from '@amityco/ts-sdk';

  const unsubscribe = MessageRepository.searchMessage(
    {
      query: 'invoice',
      exactMatch: false,
      channelId: 'channel1',
      userIds: ['user1'],
      tags: ['receipt'],
      types: ['text'],
      sortBy: 'relevance',
      orderBy: 'desc',
    },
    ({ data: messages, onNextPage, hasNextPage, loading, error }) => {
      if (error) handleError(error);

      if (!loading && messages) {
        renderResults(messages);
      }

      if (hasNextPage) onNextPage?.();
    },
  );

  unsubscribe();
  ```

  ```swift iOS theme={null}
  let options = AmityMessageSearchOptions(query: "invoice")
  options.channelId = "channel1"
  options.userIds = ["user1"]
  options.tags = ["receipt"]
  options.types = ["text"]
  options.sortBy = .relevance

  let messages = messageRepository.searchMessages(options: options)
  token = messages.observe { collection, error in
      if let error {
          handleError(error)
          return
      }

      showSuccessMessage(collection.snapshots.count)
  }
  ```

  ```kotlin Android theme={null}
  val disposable = messageRepository
      .searchMessages(query = "invoice")
      .channelId("channel1")
      .userIds(listOf("user1"))
      .tags(listOf("receipt"))
      .types(listOf(AmityMessage.DataType.TEXT))
      .sortBy("relevance")
      .build()
      .query()
      .subscribe(
          { messages -> showSuccessMessage(messages) },
          { error -> handleGeneralError(error) },
      )
  ```

  ```dart Flutter theme={null}
  final liveCollection = AmityChatClient.newMessageRepository()
      .searchMessage()
      .withQuery('invoice')
      .channelId('channel1')
      .userIds(['user1'])
      .tags(['receipt'])
      .types([AmityMessageDataType.TEXT])
      .sortBy('relevance')
      .getLiveCollection();

  liveCollection.getStreamController().stream.listen((messages) {
    final count = messages.length;
  });

  await liveCollection.loadNext();
  ```
</CodeGroup>

## Related Topics

<CardGroup cols={2}>
  <Card title="Query Channels" href="./conversation-management/channels/query-channels" icon="magnifying-glass">
    Build filtered channel lists by type, membership, tags, and state, with optional name matching.
  </Card>

  <Card title="Query Messages" href="./messaging-features/messages/query-and-filter-messages" icon="filter">
    Load and filter messages within a single channel or feed.
  </Card>

  <Card title="Get Channels" href="./conversation-management/channels/get-channel" icon="file">
    Retrieve a single channel or a known list of IDs.
  </Card>

  <Card title="Query Members" href="./conversation-management/members/query-members" icon="users">
    Find members within a channel once a result is selected.
  </Card>
</CardGroup>
