# Querying Members

The  `queryMembers`  endpoint allows you to list and paginate members for a channel. The endpoint supports filtering on numerous criteria to efficiently return member information. This endpoint is useful for channels that have large lists of members and you want to search members or if you want to display the full list of members for a channel.

#### Pagination and ordering

By default members are ordered from oldest to newest and can be paginated using offset-based pagination or by `created_at` or `user_id` fields.

Pagination by offset is the simplest to implement but it can lead to incorrect results if the list of members changes while you are paginating.

The recommended approach is to sort by "created_at" or by "user_id".

<codetabs>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val channelClient = client.channel("messaging", "general")
val filter = Filters.neutral()
val offset = 0
val limit = 10

// paginate by user_id in descending order
val sort = QuerySortByField<Member>().descByName("userId")

channelClient.queryMembers(offset, limit, filter, sort).enqueue { result ->
  when (result) {
    is Result.Success -> {
      val members: List<Member> = result.value
    }
    is Result.Failure -> {
      Log.e(TAG, String.format("There was an error %s", result.value), result.value.extractCause())
    }
  }
}

// paginate by created at in ascending order
val createdAtSort = QuerySortByField<Member>().ascByName("createdAt")

channelClient.queryMembers(offset, limit, filter, createdAtSort).enqueue { result ->
  when (result) {
    is Result.Success -> {
      val members: List<Member> = result.value
    }
    is Result.Failure -> {
      Log.e(TAG, String.format("There was an error %s", result.value), result.value.extractCause())
    }
  }
}
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
await channel.queryMembers({}, sort, {});

// returns up to 100 members ordered by created_at descending
let sort = { created_at: -1 };
await channel.queryMembers({}, sort, {});

// returns up to 100 members ordered by user_id descending
sort = { user_id: -1 };
await channel.queryMembers({}, sort, {});

// paginate by user_id in descending order
sort = { user_id: 1 };
let options = { user_id_lt: lastMember.user_id };
await channel.queryMembers({}, sort, options);

// paginate by created at in ascending order
sort = { created_at: -1 };
options = { created_at_before: lastMember.created_at };
await channel.queryMembers({}, sort, options);

// paginate using offset
options = { offset: 20 };
await channel.queryMembers({}, sort, {});
```

</codetabs-item>

<codetabs-item value="swift" label="Swift">

```swift
let memberListController = client.memberListController(
  query: .init(
    cid: .init(type: .messaging, id: "general"),
    sort: [.init(key: .createdAt, isAscending: true)]
  )
)

memberListController.synchronize() { error in
  if error == nil {
    memberListController.members
  }
}
```

</codetabs-item>

<codetabs-item value="python" label="Python">

```python
# paginate by user_id in descending order
response = channel.query_members(
  filter_conditions={},
  sort=[{"field": "user_id", "direction": 1}],
  offset=0,
  limit=10,
)

# paginate by created at in ascending order
response = channel.query_members(
  filter_conditions={},
  sort=[{"field": "created_at", "direction": -1}],
  offset=0,
  limit=10,
)
ChannelClient channelClient = client.channel("messaging", "general");
      int offset = 0;
      int limit = 10;
      FilterObject filterByName = Filters.neutral();

      // paginate by user_id in descending order
      QuerySorter<Member> sort = QuerySortByField.descByName("userId");
      channelClient.queryMembers(offset, limit, filterByName, sort, emptyList()).enqueue(result -> {
        if (result.isSuccess()) {
          List<Member> members = result.data();
        } else {
          // Handle result.error()
        }
      });

      // paginate by created at in ascending order
      QuerySorter<Member> createdAtSort = QuerySortByField.ascByName("createdAt");
      channelClient.queryMembers(offset, limit, filterByName, createdAtSort, emptyList()).enqueue(result -> {
        if (result.isSuccess()) {
          List<Member> members = result.data();
        } else {
          // Handle result.error()
        }
      });
```

</codetabs-item>

<codetabs-item value="java" label="Java">

```java
// Android SDK

ChannelClient channelClient = client.channel("messaging", "general");
int offset = 0;
int limit = 10;
FilterObject filterByName = Filters.neutral();

// paginate by user_id in descending order
QuerySorter<Member> sort = QuerySortByField.descByName("userId");
channelClient.queryMembers(offset, limit, filterByName, sort, emptyList()).enqueue(result -> {
  if (result.isSuccess()) {
    List<Member> members = result.data();
  } else {
    // Handle result.error()
  }
});

// paginate by created at in ascending order
QuerySorter<Member> createdAtSort = QuerySortByField.ascByName("createdAt");
channelClient.queryMembers(offset, limit, filterByName, createdAtSort, emptyList()).enqueue(result -> {
  if (result.isSuccess()) {
    List<Member> members = result.data();
  } else {
    // Handle result.error()
  }
 });


// Backend SDK

// paginate by user_id in descending order
ChannelQueryMembersResponse members = Channel.queryMembers()
  .sort(Sort.builder().field("user_id").direction(Direction.DESC).build())
  .limit(10)
  .request();

// paginate by created at in ascending order
ChannelQueryMembersResponse members = Channel.queryMembers()
  .sort(Sort.builder().field("created_at").direction(Direction.ASC).build())
  .limit(10)
  .request();
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
# require 'stream-chat'

# paginate by user_id in descending order
response = channel.query_members(
  filter_conditions: {},
  sort: [{"field" => "user_id", "direction" => 1}],
  offset: 0,
  limit: 10,
)

# paginate by created at in ascending order
response = channel.query_members(
  filter_conditions: {},
  sort: [{"field" => "created_at", "direction" => -1}],
  offset: 0,
  limit: 10,
)
```

</codetabs-item>

<codetabs-item value="csharp" label="C#">

```csharp
// paginate by user_id in descending order
await channelClient.QueryMembersAsync(new QueryMembersRequest
{
  FilterConditions = new Dictionary<string, object>(),
  Sorts = new[] { new SortParameter { Field = "user_id", Direction = SortDirection.Descending } },
  Limit = 10,
  Offset = 0,
});

// paginate by created at in ascending order
await channelClient.QueryMembersAsync(new QueryMembersRequest
{
  FilterConditions = new Dictionary<string, object>(),
  Sorts = new[] { new SortParameter { Field = "created_at", Direction = SortDirection.Ascending } },
  Limit = 10,
  Offset = 0,
});
```

</codetabs-item>

<codetabs-item value="php" label="PHP">

```php
// paginate by user_id in descending order
$channel->queryMembers(
 [],
 [["user_id" => 1]],
 ["limit" => 10, "offset" => 0]
);

// paginate by created at in ascending order
$channel->queryMembers(
 [],
 [["created_at" => -1]],
 ["limit" => 10, "offset" => 0]
);
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
// paginate by user_id in descending order
ch.QueryMembers(ctx, &QueryOption{
	Filter: make(map[string]interface{}),
	Offset: 1,
	Limit: 10,
},
	&SortOption{Field: "user_id", Direction: 1},
)

// paginate by created at in ascending order
ch.QueryMembers(ctx, &QueryOption{
	Filter: make(map[string]interface{}),
	Offset: 1,
	Limit: 10,
},
	&SortOption{Field: "created_at", Direction: -1},
)
```

</codetabs-item>

<codetabs-item value="unreal" label="Unreal">

```cpp
// returns up to 100 members ordered by created_at descending
{
  const TArray<FUserSortOption> Sort{{EUserSortField::CreatedAt, ESortDirection::Descending}};
  Channel->QueryMembers({}, Sort, {});
}

// returns up to 100 members ordered by user_id descending
{
  const TArray<FUserSortOption> Sort{{EUserSortField::Id, ESortDirection::Descending}};
  Channel->QueryMembers({}, Sort, {});
}

// paginate by user_id in ascending order
{
  const TArray<FUserSortOption> Sort{{EUserSortField::Id, ESortDirection::Ascending}};
  FMessagePaginationOptions Options{};
  Options.IdLt = LastMember->Id;
  Channel->QueryMembers({}, Sort, Options);
}

// paginate by created at in ascending order
{
  const TArray<FUserSortOption> Sort{{EUserSortField::CreatedAt, ESortDirection::Ascending}};
  FMessagePaginationOptions Options{};
  Options.CreatedAtBefore = LastMember->CreatedAt;
  Channel->QueryMembers({}, Sort, Options);
}

// paginate using offset
{
  const FMessagePaginationOptions Options{
    {},  // Limit
    20,  // Offset
  };
  Channel->QueryMembers({}, {}, Options);
}
```

</codetabs-item>

<codetabs-item value="unity" label="Unity">

```csharp
var filters = new Dictionary<string, object>
{
  {
    "id", new Dictionary<string, object>
    {
      { "$in", new[] { "user-id-1", "user-id-2" } }
    }
  }
};

// Pass limit and offset to control the page or results returned
// Limit - how many records per page
// Offset - how many records to skip
var membersResult = await channel.QueryMembers(filters, limit: 30, offset: 0);
```

</codetabs-item>

</codetabs>

<admonition type="info">

Stream Chat does not run MongoDB on the backend, only a [subset](/chat/docs/<framework>/#query_syntax/) of the query options are available.

</admonition>

Here’s some example of how you can query the list of members:

<codetabs>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val channelClient = client.channel("messaging", "general")

val offset = 0 // Use this value for pagination
val limit = 10
val sort = QuerySortByField<Member>()

// Channel members can be queried with various filters
// 1. Create the filter, e.g query members by user name
val filterByName = Filters.eq("name", "tommaso")
// 2. Call queryMembers with that filter
channelClient.queryMembers(offset, limit, filterByName, sort).enqueue { result ->
  when (result) {
    is Result.Success -> {
      val members: List<Member> = result.value
    }
    is Result.Failure -> {
      Log.e(TAG, String.format("There was an error %s", result.value), result.value.extractCause())
    }
  }
}

// Here are some other commons filters you can use:

// Autocomplete members by user name (names containing "tom")
val filterByAutoCompleteName = Filters.autocomplete("name", "tom")

// Query member by id
val filterById = Filters.eq("id", "tommaso")

// Query multiple members by id
val filterByIds = Filters.`in`("id", listOf("tommaso", "thierry"))

// Query channel moderators
val filterByModerator = Filters.eq("is_moderator", true)

// Query for banned members in channel
val filterByBannedMembers = Filters.eq("banned", true)

// Query members with pending invites
val filterByPendingInvite = Filters.eq("invite", "pending")

// Query all the members
val filterByNone = Filters.neutral()

// Results can also be ordered with the QuerySortByField param
// For example, this will order results by member creation time, descending
val createdAtDescendingSort = QuerySortByField<Member>().desc("created_at")
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
// query members by user.name
channel.queryMembers({'name':'tommaso'})

// autocomplete members by user name
channel.queryMembers({name:{"$autocomplete":'tomm'}})

// query member by id
channel.queryMembers({user_id:'tommaso'})

// query multiple members by id
channel.queryMembers({user_id:{'$in:'['tommaso','thierry']}})

// query channel moderators
channel.queryMembers({is_moderator:true})

// query for banned members in channel
channel.queryMembers({banned:true})

// query members with pending invites
channel.queryMembers({invite:'pending'})

// query members who joined the channel directly or accepted an invite
channel.queryMembers({joined: true})

// query members who have rejected invite or have pending invite
channel.queryMembers({joined: false}

// query all the members
channel.queryMembers({})

// order results by member created at descending
channel.queryMembers({}, {created_at:-1})

// you can also query members by custom data
client.queryMembers({ 'user.email':'awesome@getstream.io' })

client.queryMembers({ 'subscription':'gold_plan' })
```

</codetabs-item>

<codetabs-item value="swift" label="Swift">

```swift
// > import StreamChat

// query by user.name
let controller = chatClient.memberListController(
  query: .init(cid: .init(type: .messaging, id: "general"), filter: .equal(.name, to: "tommaso"))
)

controller.synchronize { error in
  // handle error / access members
  print(error ?? controller.members)
}

// query members with name containing tom
let controller1 = chatClient.memberListController(
  query: .init(cid: .init(type: .messaging, id: "general"), filter: .query(.name, text: "tom"))
)

controller1.synchronize { error in
  // handle error / access members
  print(error ?? controller1.members)
}

// autocomplete members by user name
let controller2 = chatClient.memberListController(
  query: .init(cid: .init(type: .messaging, id: "general"), filter: .autocomplete(.name, text: "tom"))
)

controller2.synchronize { error in
  // handle error / access members
  print(error ?? controller2.members)
}

// query member by id
let controller3 = chatClient.memberListController(
  query: .init(cid: .init(type: .messaging, id: "general"), filter: .equal(.id, to: "tommaso"))
)

controller3.synchronize { error in
  // handle error / access members
  print(error ?? controller3.members)
}

// query multiple members by id
let controller4 = chatClient.memberListController(
  query: .init(cid: .init(type: .messaging, id: "general"), filter: .in(.id, values: ["tommaso", "thierry"]))
)

controller4.synchronize { error in
  // handle error / access members
  print(error ?? controller4.members)
}

// query channel moderators
let controller5 = chatClient.memberListController(
  query: .init(cid: .init(type: .messaging, id: "general"), filter: .equal(.isModerator, to: true))
)

controller5.synchronize { error in
  // handle error / access members
  print(error ?? controller5.members)
}

// query for banned members in channel
let controller6 = chatClient.memberListController(
  query: .init(cid: .init(type: .messaging, id: "general"), filter: .equal(.isBanned, to: true))
)

controller6.synchronize { error in
  // handle error / access members
  print(error ?? controller6.members)
}

// query members with pending invites
let controller7 = chatClient.memberListController(
  query: .init(cid: .init(type: .messaging, id: "general"), filter: .equal("invite", to: "pending"))
)

controller7.synchronize { error in
  // handle error / access members
  print(error ?? controller7.members)
}

// query all the members
let controller8 = chatClient.memberListController(
  query: .init(cid: .init(type: .messaging, id: "general"), filter: .none)
)

controller8.synchronize { error in
  // handle error / access members
  print(error ?? controller8.members)
}

// paginate channel members
controller8.loadNextMembers(limit: 10) { error in
  // handle error / access members
  print(error ?? controller8.members)
}

// order results by member created at descending
let controller9 = chatClient.memberListController(
  query: .init(cid: .init(type: .messaging, id: "general"), sort: [.init(key: .createdAt, isAscending: false)])
)

controller9.synchronize { error in
  // handle error / access members
  print(error ?? controller9.members)
}
```

</codetabs-item>

<codetabs-item value="python" label="Python">

```python
# query members by user.name
response = channel.query_members(
      filter_conditions={"name": "tommaso"},
      sort=[{"field": "created_at", "direction": 1}],
    )

# query members with name containing tom
response = channel.query_members( filter_conditions={"name": {"$q": "tom"}} )

# autocomplete members by user name
response = channel.query_members( filter_conditions={"name": {"$autocomplete": "tomm"}} )

# query member by id
response = channel.query_members( filter_conditions={"id": "tommaso"} )

# query multiple members by id
response = channel.query_members( filter_conditions={"id": {"$in":['tommaso','thierry']}} )

# query channel moderators
response = channel.query_members( filter_conditions={"is_moderator": True} )

# query for banned members in channel
response = channel.query_members( filter_conditions={"banned": True})

# query members with pending invites
response = channel.query_members( filter_conditions={"invite": "pending"} )
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
// query members by user.name
channel.queryMembers(
 filter: Filter.equal('name': 'tommaso'),
);

// autocomplete members by user name
channel.queryMembers(
 filter: Filter.autocomplete('name', 'tomm'),
);

// query member by id
channel.queryMembers(
 filter: Filter.equal('id', 'tommaso'),
);

// query multiple members by id
channel.queryMembers(
 filter: Filter.in_('id', ['tommaso', 'thierry']),
);

// query channel moderators
channel.queryMembers(
 filter: Filter.equal('is_moderator', true),
);

// query for banned members in channel
channel.queryMembers(
 filter: Filter.equal('banned', true),
);

// query members with pending invites
channel.queryMembers(
 filter: Filter.equal('invite', 'pending'),
);

// query all the members
channel.queryMembers();

// paginate channel members
channel.queryMembers(
 pagination: PaginationParams(
  limit: 10,
  offset: 10,
 ),
);

// order results by member created at descending
channel.queryMembers(
 sort: [
  SortOption(
   'created_at', direction: SortOption.DESC,
  ),
 ],
);

// query for user.email (currently the only supported custom field)
channel.queryMembers(
 filter: Filter.equal('email', 'marcelo@getstream.io'),
);
```

</codetabs-item>

<codetabs-item value="unreal" label="Unreal">

```cpp
// query members by user.name
Channel->QueryMembers(FFilter::Equal(TEXT("name"), TEXT("tommaso")));

// autocomplete members by user name
Channel->QueryMembers(FFilter::Autocomplete(TEXT("name"), TEXT("tomm")));

// query member by id
Channel->QueryMembers(FFilter::Equal(TEXT("id"), TEXT("tommaso")));

// query multiple members by id
Channel->QueryMembers(FFilter::In(TEXT("id"), {TEXT("tommaso"), TEXT("thierry")}));

// query channel moderators
Channel->QueryMembers(FFilter::Equal(TEXT("is_moderator"), true));

// query for banned members in channel
Channel->QueryMembers(FFilter::Equal(TEXT("banned"), true));

// query members with pending invites
Channel->QueryMembers(FFilter::Equal(TEXT("invite"), TEXT("pending")));

// query all the members
Channel->QueryMembers();

// paginate channel members
Channel->QueryMembers({}, {}, {10, 10});

// order results by member created at descending
Channel->QueryMembers({}, {{EUserSortField::CreatedAt, ESortDirection::Descending}});

// query for user.email (currently the only supported custom field)
Channel->QueryMembers(FFilter::Equal(TEXT("email"), TEXT("marcelo@getstream.io")));
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
# query members by user.name
response = channel.query_members(
  filter_conditions: {"name" => "tommaso"},
  sort: [{"field" => "created_at", "direction" => 1}]
)

# query members with name containing tom
response = channel.query_members( filter_conditions: {"name" => {"$q" => "tom"}} )

# autocomplete members by user name
response = channel.query_members( filter_conditions: {"name" => {"$autocomplete" => "tomm"}} )

# query member by id
response = channel.query_members( filter_conditions: {"id" => "tommaso"} )

# query multiple members by id
response = channel.query_members( filter_conditions: {"id" => {"$in" =>['tommaso','thierry']}} )

# query channel moderators
response = channel.query_members( filter_conditions: {"is_moderator" => true} )

# query for banned members in channel
response = channel.query_members( filter_conditions: {"banned" => true})

# query members with pending invites
response = channel.query_members( filter_conditions: {"invite" => "pending"} )
```

</codetabs-item>

<codetabs-item value="csharp" label="C#">

```csharp
// paginate by user_id in descending order
await channelClient.QueryMembersAsync(new QueryMembersRequest
{
  FilterConditions = new Dictionary<string, object> { { "name", "tommaso" } },
});

// query members with name containing tom
await channelClient.QueryMembersAsync(new QueryMembersRequest
{
  FilterConditions = new Dictionary<string, object>
  {
    { "name", new Dictionary<string, string> { { "$q", "tom" } } },
  },
});

// autocomplete members by user name
await channelClient.QueryMembersAsync(new QueryMembersRequest
{
  FilterConditions = new Dictionary<string, object>
  {
    { "name", new Dictionary<string, string> { { "$autocomplete", "tomm" } } },
  },
});

// query member by id
await channelClient.QueryMembersAsync(new QueryMembersRequest
{
  FilterConditions = new Dictionary<string, object> { { "id", "tommaso" } },
});

// query multiple members by id
await channelClient.QueryMembersAsync(new QueryMembersRequest
{
  FilterConditions = new Dictionary<string, object>
  {
    { "id", new Dictionary<string, string[]> { { "$in", new[] {"thierry", "tommaso"} } } },
  },
});

// query channel moderators
await channelClient.QueryMembersAsync(new QueryMembersRequest
{
  FilterConditions = new Dictionary<string, bool> { { "is_moderator", true } },
});

// query for banned members in channel
await channelClient.QueryMembersAsync(new QueryMembersRequest
{
  FilterConditions = new Dictionary<string, bool> { { "banned", true } },
});

// query members with pending invites
await channelClient.QueryMembersAsync(new QueryMembersRequest
{
  FilterConditions = new Dictionary<string, string> { { "invite", "pending" } },
});
```

</codetabs-item>

<codetabs-item value="php" label="PHP">

```php
// query members by user.name
$channel->queryMembers(
 ["name" => "tommaso"],
 [["created_at" => 1]],
 ["limit" => 10, "offset" => 0]
);

// query members with name containing tom
$channel->queryMembers(["name" => [ "$q" => "tomm" ]]);

// autocomplete members by user name
$channel->queryMembers(["name" => [ "$autocomplete" => "tomm" ]]);

// query member by id
$channel->queryMembers(["id" => "tommaso" ]);

// query multiple members by id
$channel->queryMembers(["id" => [ "$in" => ["thierry", "tommaso"] ]]);

// query channel moderators
$channel->queryMembers(["is_moderator" => true]);

// query for banned members in channel
$channel->queryMembers(["banned" => true]);

// query members with pending invites
$channel->queryMembers(["invite" => "pending"]);
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
// query members by user.name
ch.QueryMembers(ctx, &QueryOption{
 	Filter: map[string]interface{}{
			"name": "tommaso",
	},
	Offset: 0,
	Limit: 10,
},
	&SortOption{Field: "created_at", Direction: 1},
)

// query members with name containing tom
ch.QueryMembers(ctx, &QueryOption{
 	Filter: map[string]interface{}{
			"name": map[string]interface{}{"$q": "tomm"},
	},
})

// autocomplete members by user name
ch.QueryMembers(ctx, &QueryOption{
 	Filter: map[string]interface{}{
			"name": map[string]interface{}{"$autocomplete": "tomm"},
	},
})

// query member by id
ch.QueryMembers(ctx, &QueryOption{
 	Filter: map[string]interface{}{
			"id": "tommaso",
	},
})

// query multiple members by id
ch.QueryMembers(ctx, &QueryOption{
 	Filter: map[string]interface{}{
			"id": map[string]interface{}{"$in": []string{"thierry", "tommaso"}},
	},
})

// query channel moderators
ch.QueryMembers(ctx, &QueryOption{
 	Filter: map[string]interface{}{
			"is_moderator": true,
	},
})

// query for banned members in channel
ch.QueryMembers(ctx, &QueryOption{
 	Filter: map[string]interface{}{
			"banned": true,
	},
})

// query members with pending invites
ch.QueryMembers(ctx, &QueryOption{
 	Filter: map[string]interface{}{
			"invite": "pending",
	},
})
```

</codetabs-item>

<codetabs-item value="java" label="Java">

```java
// Android SDK

ChannelClient channelClient = client.channel("messaging", "general");

int offset = 0; // Use this value for pagination
int limit = 10;
QuerySortByField<Member> sort = new QuerySortByField<>();

// Channel members can be queried with various filters
// 1. Create the filter, e.g query members by user name
FilterObject filterByName = Filters.eq("name", "tommaso");
// 2. Call queryMembers with that filter
channelClient.queryMembers(offset, limit, filterByName, sort, emptyList()).enqueue(result -> {
  if (result.isSuccess()) {
    List<Member> members = result.data();
  } else {
    // Handle result.error()
  }
});

// Here are some other commons filters you can use:

// Autocomplete members by user name (names containing "tom")
FilterObject filterByAutoCompleteName = Filters.autocomplete("name", "tom");

// Query member by id
FilterObject filterById = Filters.eq("id", "tommaso");

// Query multiple members by id
FilterObject filterByIds = Filters.in("id", Arrays.asList("tommaso", "thierry"));

// Query channel moderators
FilterObject filterByModerator = Filters.eq("is_moderator", true);

// Query for banned members in channel
FilterObject filterByBannedMembers = Filters.eq("banned", true);

// Query members with pending invites
FilterObject filterByPendingInvite = Filters.eq("invite", "pending");

// Query all the members
FilterObject filterByNone = NeutralFilterObject.INSTANCE;

// We can order the results too with QuerySortByField param
// Here example to order results by member created at descending
QuerySortByField<Member> createdAtDescendingSort = QuerySortByField.descByName("createdAt");

// Backend SDK
// Channel members can be queried with various filters
// 1. Create the filter, e.g query members by user name
Map<String, Object> filterById = FilterCondition.eq("name", "tommaso");

// 2. Call queryMembers with that filter
ChannelQueryMembersResponse members = Channel.queryMembers()
 .filterConditions(filterByName)
 .request();

// Here are some other commons filters you can use:

// Autocomplete members by user name (names containing "tom")
Map<String, Object> filterByAutoCompleteName = FilterCondition.autocomplete("name", "tom");

// Query member by id
Map<String, Object> filterById = FilterCondition.eq("id", "tommaso");

// Query multiple members by id
Map<String, Object> filterByIds = FilterCondition.in("id", Arrays.asList("tommaso", "thierry"));

// Query channel moderators
Map<String, Object> filterByModerator = FilterCondition.eq("is_moderator", true);

// Query for banned members in channel
Map<String, Object> filterByBannedMembers = FilterCondition.eq("banned", true);

// Query members with pending invites
Map<String, Object> filterByPendingInvite = FilterCondition.eq("invite", "pending");

// We can order the results too with Sort param
// Here example to order results by member created at descending
Sort createdAtDescendingSort = Sort
 .builder()
 .field("created_at")
 .direction(Sort.Direction.DESC)
 .build();
```

</codetabs-item>

<codetabs-item value="unity" label="Unity">

```csharp
var channel = await Client.GetOrCreateChannelWithIdAsync(ChannelType.Messaging, channelId: "my-channel-id");

var filters = new Dictionary<string, object>
{
  {
    "id", new Dictionary<string, object>
    {
      { "$in", new[] { "user-id-1", "user-id-2" } }
    }
  }
};

// Pass limit and offset to control the page or results returned
// Limit - how many records per page
// Offset - how many records to skip
var membersResult = await channel.QueryMembers(filters, limit: 30, offset: 0);
```

</codetabs-item>

</codetabs>

### Query Parameters

| name    | type   | description                                                                       | default                | optional |
| ------- | ------ | --------------------------------------------------------------------------------- | ---------------------- | -------- |
| filters | object | The query filters to use. You can query on any of the custom fields defined above | {}                     |          |
| sort    | object | the sort parameters                                                               | { created_at:1}        | ✓        |
| options | object | pagination options                                                                | { limit:100, offset:0} | ✓        |

<admonition type="info">

By default when query members does not have any filter and it will match all members on your channel.

</admonition>

### Member Queryable Built-In Fields

The following fields can be used to filter your query results

| Name         | Type                                                               | Description                                         | supported operators         | Example                 |
| ------------ | ------------------------------------------------------------------ | --------------------------------------------------- | --------------------------- | ----------------------- |
| id           | string                                                             | the id of the user                                  | $eq $in                     | tom                     |
| name         | string                                                             | the name of the user                                | $eq, $in, $autocomplete, $q | Tommaso                 |
| channel_role | string                                                             | the member role                                     | $eq                         | channel_moderator       |
| banned       | boolean                                                            | the banned status                                   | $eq                         | false                   |
| invite       | string, must be one of these values: (pending, accepted, rejected) | the status of the invite                            | $eq                         | pending                 |
| joined       | boolean                                                            | whether member is joined the channel or not         | $eq                         | true                    |
| created_at   | string, must be formatted as an RFC3339 timestamp                  | the time that the member was created                | $eq, $gt, $gte, $lt, $lte   | 2021-01-15T09:30:20.45Z |
| updated_at   | string, must be formatted as an RFC3339 timestamp                  | the time the member was last updated                | $eq, $gt, $gte, $lt, $lte   | 2021-01-15T09:30:20.45Z |
| last_active  | string, must be formatted as an RFC3339 timestamp                  | the time the user was last active                   | $eq, $gt, $gte, $lt, $lte   | 2021-01-15T09:30:20.45Z |
| cid          | string                                                             | the cid of the channel that the user is a member of | $eq                         | messaging:general       |
| user.email   | string                                                             | the 'email' property of the user                    | $eq, $in, $autcomplete      | <user@example.com>      |

Also, you can pass any field available in the custom data.

### Query Options

| name                       | type    | description                                                                 | default | optional |
| -------------------------- | ------- | --------------------------------------------------------------------------- | ------- | -------- |
| limit                      | integer | The number of members to return (max is 100)                                | 100     | ✓        |
| offset                     | integer | The offset (max is 1000)                                                    | 0       | ✓        |
| user_id_lt                 | string  | Pagination option: excludes members with ID greater or equal the value      | -       | ✓        |
| user_id_lte                | string  | Pagination option: excludes members with ID greater than the value          | -       | ✓        |
| user_id_gt                 | string  | Pagination option: excludes members with ID less or equal the value         | -       | ✓        |
| user_id_gte                | string  | Pagination option: excludes members with ID less than the value             | -       | ✓        |
| created_at_after           | string  | Pagination option: select members created after the date (RFC399)           | -       | ✓        |
| created_at_before          | string  | Pagination option: select members created before the date (RFC399)          | -       | ✓        |
| created_at_before_or_equal | string  | Pagination option: select members created before or equal the date (RFC399) | -       | ✓        |
| created_at_after_or_equal  | string  | Pagination option: select members created after or equal the date (RFC399)  | -       | ✓        |

### Response

| Field Name | Description                            |
| ---------- | -------------------------------------- |
| members    | The list of members matching the query |

---

This page was last updated at 2025-08-29T10:36:17.406Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/unreal/query_members/](https://getstream.io/chat/docs/unreal/query_members/).