> ## Documentation Index
> Fetch the complete documentation index at: https://social-b97141fb-feat-user-history-moderation-detail.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Search and Query Users

> Search for users by display name and query paginated user collections in social.plus SDK.

Use the user repository when your app needs to find people by display name or browse a paginated user list. Search is for keyword-driven flows such as member pickers, while query is for directory-style lists where sorting and pagination matter more than a search keyword.

<Info>
  Deleted users are automatically excluded from search and query results.
</Info>

## Parameters

This page covers two user-list operations. Choose the operation first, then use the inputs table in each section for the exact SDK call shape.

| Operation | Use when | Required inputs | Platforms |
| - | - | - | - |
| Search users by display name | You have a display-name keyword and want matching users. | Display-name keyword, callback or collection observer where required. | TypeScript, iOS, Android, Flutter |
| Query users | You need a paginated user list without a search keyword. | Callback or sort option where required. | TypeScript, iOS, Android, Flutter |

## Search users by display name

Use search when the user types a display-name keyword. Search keywords must be at least 3 characters long. When a keyword is provided, the server ranks matching results by search relevance; supported sort options can then control the returned order.

### Selecting which fields to match (`searchBy`)

By default the keyword is matched against **all** searchable user fields (display name, user id, and profile handle), so a keyword can surface users that match only by their user id. Provide `searchBy` to restrict which fields are matched — for example, display name only — so results exclude user-id-only matches.

* Omitting `searchBy` (or passing an empty value) keeps the default behavior, so existing integrations are unaffected.
* Supported field options: `displayName`, `userId`, `profileHandle`.

| Field | Platforms | TypeScript | iOS | Android |
| - | - | - | - | - |
| Display name | TypeScript, iOS, Android | `SearchUsersByEnum.DISPLAY_NAME` | `.displayName` | `AmitySearchUserBy.DISPLAY_NAME` |
| User ID | TypeScript, iOS, Android | `SearchUsersByEnum.USER_ID` | `.userId` | `AmitySearchUserBy.USER_ID` |
| Profile handle | TypeScript, iOS, Android | `SearchUsersByEnum.PROFILE_HANDLE` | `.profileHandle` | `AmitySearchUserBy.PROFILE_HANDLE` |

TypeScript types `searchBy` as an array of `SearchUsersByEnum` values, exported from the package root. Plain string literals do not type-check.

<Note>
  Platform support for `searchBy` differs. iOS, Android, and TypeScript expose it on user search; Flutter support is not yet available.
</Note>

### Inputs

| Platform | Method | Required inputs | Optional inputs | Result shape |
| - | - | - | - | - |
| TypeScript | `UserRepository.searchUsers(params, callback)` | `displayName` (the keyword), callback | `searchBy`, `limit`, `matchType` | Starts a live collection observer and returns an unsubscriber. |
| iOS | `userRepository.searchUsers(keyword, searchBy:, sortBy:, matchType:)` | `keyword`, `searchBy`, `sortBy` | `matchType` | Returns a live collection observed with an `AmityNotificationToken`. |
| Android | `userRepository.searchUsers(keyword).build().query()` | `keyword` | `searchBy(...)`, `sortBy(...)`, `matchType(...)` | Returns `Flowable<PagingData<AmityUser>>`. |
| Flutter | `AmityCoreClient.newUserRepository().searchUserByDisplayName(keyword)` | `keyword` | `sortBy(...)`, `matchType(...)`, paging token, limit | Returns paging data through the query builder. |

<Warning>
  TypeScript `UserRepository.searchUserByDisplayName(params, callback)` is deprecated in favour of `searchUsers(params, callback)`. Both accept the same parameters and return the same live collection, so switching is a rename. The deprecated method will be removed in a future major version.
</Warning>

<Note>
  TypeScript search parameters intentionally do not include `sortBy`; use `getUsers(...)` when you need TypeScript user-list sorting.
</Note>

### Special character handling

<Info>
  With display-name sorting, users are sorted alphabetically by their display names using ICU collation for the English locale. This means that special characters such as Ä are treated as variants of A. For example, a sorted list might appear as: **adam, Älex, Alice, Arthur, charlie, Kristen**.

  When providing a search keyword, the API performs an exact-match lookup for special characters:

  * Searching for "Äli" only returns users whose display name contains "Äli", such as "Älise".
  * Searching for "Alice" does not return "Älice".
</Info>

Use the platform search method to retrieve users whose display name matches the search keyword.

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

  let loadMoreUsers: (() => void) | undefined;

  const unsubscribe = UserRepository.searchUsers(
    // `searchBy` is optional; omit it to match all fields.
    { displayName: 'Joe', limit: 20, searchBy: [SearchUsersByEnum.DISPLAY_NAME] },
    ({ data: users, loading, error, hasNextPage, onNextPage }) => {
      if (loading) return;

      if (error) {
        console.error('Failed to search users', error);
        return;
      }

      console.log(`Found ${users.length} users`);
      console.log(`More pages available: ${hasNextPage}`);
      loadMoreUsers = onNextPage;
    },
  );

  // Call loadMoreUsers?.() from your load-more action.
  // Call unsubscribe() when the screen no longer needs search updates.
  ```

  ```swift iOS theme={null}
  var token: AmityNotificationToken?

  func searchUserExample() {
      // `searchBy` selects which fields the keyword is matched against.
      // Use [.displayName] to match display name only; pass [] to keep the
      // default behavior (match all searchable fields).
      let liveCollection = userRepository.searchUsers(
          "<keyword>",
          searchBy: [.displayName],
          sortBy: .displayName,
          matchType: .default
      )
      token = liveCollection.observe { collection, error in
          let users = collection.snapshots
          print("Found \(users.count) users")
      }
  }
  ```

  ```kotlin Android theme={null}
  fun searchUsers(userRepository: AmityUserRepository) {
      userRepository.searchUsers("Brian")
          .searchBy(listOf(AmitySearchUserBy.DISPLAY_NAME)) // optional; omit to match all fields
          .sortBy(sortOption = AmityUserSortOption.DISPLAYNAME) // optional
          .build()
          .query()
          .doOnNext { users: PagingData<AmityUser> ->
              // PagingData<AmityUser>
          }
          .doOnError { error ->
              Log.e("UserRepo", "Failed to search users", error)
          }
          .subscribe()
  }
  ```

  ```dart Flutter theme={null}
  final _amityUsers = <AmityUser>[];
  late PagingController<AmityUser> _amityUsersController;

  void searchUserByDisplayName(String keyword) {
    _amityUsersController = PagingController(
      pageFuture: (token) => AmityCoreClient.newUserRepository()
          .searchUserByDisplayName(keyword)
          .sortBy(AmityUserSortOption.DISPLAY)
          .matchType(AmityUserSearchMatchType.DEFAULT)
          .getPagingData(token: token, limit: 20),
      pageSize: 20,
    )..addListener(
        () {
          if (_amityUsersController.error == null) {
            _amityUsers.clear();
            _amityUsers.addAll(_amityUsersController.loadedItems);
          }
        },
      );
  }
  ```
</CodeGroup>

## Query users

Use `getUsers()` when you need a paginated user list without a display-name keyword. TypeScript query sorting supports `firstCreated` and `lastCreated`; iOS, Android, and Flutter also expose display-name sorting.

### Inputs

| Platform | Method | Required inputs | Optional inputs | Result shape |
| - | - | - | - | - |
| TypeScript | `UserRepository.getUsers(params, callback)` | callback | `sortBy`, `limit`, `filter`, `matchType` | Starts a live collection observer and returns an unsubscriber. |
| iOS | `userRepository.getUsers(sortBy)` | `sortBy` | None in this call shape | Returns a live collection observed with an `AmityNotificationToken`. |
| Android | `userRepository.getUsers().build().query()` | None | `sortBy(...)` | Returns `Flowable<PagingData<AmityUser>>`. |
| Flutter | `AmityCoreClient.newUserRepository().getUsers()` | None | `sortBy(...)`, paging token, limit | Returns paging data through the query builder. |

<Info>
  Deleted users are excluded from query results.
</Info>

Use the platform query method when you need a paginated user list rather than keyword search.

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

  let loadMoreUsers: (() => void) | undefined;

  const unsubscribe = UserRepository.getUsers(
    { sortBy: 'lastCreated', limit: 20 },
    ({ data: users, loading, error, hasNextPage, onNextPage }) => {
      if (loading) return;

      if (error) {
        console.error('Failed to query users', error);
        return;
      }

      console.log(`Loaded ${users.length} users`);
      console.log(`More pages available: ${hasNextPage}`);
      loadMoreUsers = onNextPage;
    },
  );

  // Call loadMoreUsers?.() from your load-more action.
  // Call unsubscribe() when the screen no longer needs user list updates.
  ```

  ```swift iOS theme={null}
  var token: AmityNotificationToken?

  func queryUsersExample() {
      let liveCollection = userRepository.getUsers(.displayName)
      token = liveCollection.observe { collection, error in
          let users = collection.snapshots
          print("Loaded \(users.count) users")
      }
  }
  ```

  ```kotlin Android theme={null}
  fun queryUsers(userRepository: AmityUserRepository) {
      userRepository.getUsers()
          .sortBy(sortOption = AmityUserSortOption.DISPLAYNAME) // optional
          .build()
          .query()
          .doOnNext { users: PagingData<AmityUser> ->
              // PagingData<AmityUser>
          }
          .doOnError { error ->
              Log.e("UserRepo", "Failed to query users", error)
          }
          .subscribe()
  }
  ```

  ```dart Flutter theme={null}
  final _amityUsers = <AmityUser>[];
  late PagingController<AmityUser> _amityUsersController;

  void getUsers(AmityUserSortOption sortOption) {
    _amityUsersController = PagingController(
      pageFuture: (token) => AmityCoreClient.newUserRepository()
          .getUsers()
          .sortBy(sortOption)
          .getPagingData(token: token, limit: 20),
      pageSize: 20,
    )..addListener(
        () {
          if (_amityUsersController.error == null) {
            _amityUsers.clear();
            _amityUsers.addAll(_amityUsersController.loadedItems);
          }
        },
      );
  }
  ```
</CodeGroup>

## Platform notes

* `searchBy` (where supported) restricts which fields the keyword matches; omit it to keep the default behavior of matching all searchable fields (display name, user id, profile handle). Flutter does not yet expose `searchBy`.
* TypeScript `searchUsers(...)` starts a live collection observer, but its search params do not expose `sortBy`. `searchUserByDisplayName(...)` is a deprecated alias with the same behaviour.
* iOS search and query methods require an `AmityUserSortOption`.
* Android and Flutter default user search/query sorting to display name when no explicit sort is provided.
* Android takes `searchBy` as a list — `searchBy(listOf(AmitySearchUserBy.DISPLAY_NAME))`. Import the enum from `com.amity.socialcloud.sdk.model.core.search.AmitySearchUserBy`; it lives in a different package from `AmityUserSortOption` and `AmityUserSearchMatchType` (`com.amity.socialcloud.sdk.api.core.user.search`).
* Use pagination controls from the callback, live collection, `PagingData`, or Flutter `PagingController` instead of loading all users at once.

## Related topics

<CardGroup cols={2}>
  <Card title="Get User Information" href="./get-user-information" icon="user">
    Retrieve one user, batch lookup users where supported, or query user collections.
  </Card>

  <Card title="Update User Information" href="./update-user-information" icon="pencil">
    Modify user profile fields.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.