# Invites

### Inviting Users

Stream Chat provides the ability to invite users to a channel. Upon invitation, the end-user will receive a notification that they were invited to the specified channel.

<admonition type="info">

Most of our SDKs have a helper method for member invitation which uses the Update Channel API endpoint.

</admonition>

See the following for an example on how to invite a user by user ID:

<codetabs>

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

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

channelClient.inviteMembers(memberIds = listOf("nick")).enqueue { result ->
  if (result is Result.Success) {
    val channel: Channel = result.value
  } else {
    // Handle Result.Failure
  }
}
```

</codetabs-item>

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

```js
await channel.inviteMembers(["nick"]);
```

</codetabs-item>

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

```php
$channel->inviteMembers(['thierry']);
```

</codetabs-item>

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

```dart
final invite = client.channel("messaging", id: "awesome-chat",
  extraData: {
   "name": "Founder Chat",
   "members": ["thierry", "tommaso"],
   "invites": ["nick"],
  });

await invite.create();
```

</codetabs-item>

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

```swift
let controller = client.channelController(for: .init(type: .messaging, id: "general"))

controller.inviteMembers(userIds: ["thierry"])
```

</codetabs-item>

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

```cpp
// Not yet supported in the Unreal SDK
```

</codetabs-item>

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

```python
channel.invite_members(["thierry"])
```

</codetabs-item>

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

```ruby
# require 'stream-chat'

channel.invite_members(['thierry'])
```

</codetabs-item>

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

```go
channel.InviteMembers(ctx, "thierry")
```

</codetabs-item>

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

```csharp
await channelClient.InviteAsync("<channel-type>", "<channel-id>", "thierry");
```

</codetabs-item>

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

```java
// Android SDK
ChannelClient channelClient = client.channel("messaging", "general");

List<String> memberIds = Arrays.asList("thierry", "tommaso");
Map<String, Object> data = new HashMap<>();
data.put("invites", Arrays.asList("nick"));

channelClient.create(memberIds, data).enqueue(result -> {
  if (result.isSuccess()) {
    Channel channel = result.data();
  } else {
    // Handle result.error()
  }
 });


// Backend SDK
Channel.update("messaging", "general")
  .invites(Arrays.asList("thierry", "tommaso"))
  .request();
```

</codetabs-item>

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

```csharp
// Invite IStreamUser collection as new members
await channel.InviteMembersAsync(users);

// Or add by ID
await channel.InviteMembersAsync("some-user-id-1", "some-user-id-2");
```

</codetabs-item>

</codetabs>

### Accepting an Invite

In order to accept an invite, you must use call the `acceptInvite` method. The `acceptInvite` method accepts an object with an optional `message` property. Please see below for an example of how to call `acceptInvite` :

<admonition type="info">

The `message` can be used for system messages for display within the channel (e.g. "Nick joined this channel!").

</admonition>

<admonition type="info">

Unread counts are not incremented for a channel for which a user is a member of but has a pending invite.

</admonition>

<codetabs>

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

```kotlin
channelClient.acceptInvite(
  message = "Nick joined this channel!"
).enqueue { result ->
  if (result is Result.Success) {
    val channel: Channel = result.value
  } else {
    // Handle Result.Failure
  }
}
```

</codetabs-item>

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

```js
// initialize the channel
const channel = client.channel("messaging", "awesome-chat");

// accept the invite
await channel.acceptInvite({
  message: { text: "Nick joined this channel!" },
});

// accept the invite server side
await channel.acceptInvite({ user_id: "nick" });
```

</codetabs-item>

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

```php
// initialize the channel
$channel = $client->Channel('messaging', 'team-chat-5');

// accept the invite
$accept = $channel->acceptInvite(['user_id'=>'elon']);
```

</codetabs-item>

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

```dart
final channel = client.channel("messaging", id: "awesome-chat");
await channel.acceptInvite();
```

</codetabs-item>

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

```swift
let controller = client.channelController(for: .init(type: .messaging, id: "general"))


controller.acceptInvite()
```

</codetabs-item>

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

```cpp
// Not yet supported in the Unreal SDK
```

</codetabs-item>

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

```csharp
await channelClient.AcceptInviteAsync("<channel-type>", "<channel-id>", "thierry");
```

</codetabs-item>

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

```python
channel.accept_invite("thierry")
```

</codetabs-item>

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

```ruby
channel.accept_invite("thierry")
```

</codetabs-item>

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

```go
channel.AcceptInvite(ctx, "thierry", nil)
```

</codetabs-item>

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

```java
// Android SDK
channelClient.acceptInvite("Nick joined this channel!").enqueue(result -> {
  if (result.isSuccess()) {
    Channel channel = result.data();
  } else {
    // Handle result.error()
  }
});

// Backend SDK
Channel.update("messaging", "general")
  .acceptInvite(true)
  .userId("nick")
  .message(MessageRequestObject.builder().text("Nick joined the channel").build())
  .request();
```

</codetabs-item>

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

```csharp
await channel.AcceptInviteAsync();
```

</codetabs-item>

</codetabs>

### Rejecting an Invite

To reject an invite, call the `rejectInvite` method. This method does not require a user ID as it pulls the user ID from the current session in store from the `connectUser` call.

<codetabs>

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

```kotlin
channelClient.rejectInvite().enqueue { result ->
  if (result is Result.Success) {
    // Invite rejected
  } else {
    // Handle Result.Failure
  }
}
```

</codetabs-item>

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

```js
await channel.rejectInvite();

//server side
await channel.rejectInvite({ user_id: "rob" });
```

</codetabs-item>

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

```php
$reject = $channel->rejectInvite(['user_id'=>'elon']);
```

</codetabs-item>

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

```dart
await channel.rejectInvite();
```

</codetabs-item>

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

```swift
let controller = client.channelController(for: .init(type: .messaging, id: "general"))

controller.rejectInvite()
```

</codetabs-item>

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

```cpp
// Not yet supported in the Unreal SDK
```

</codetabs-item>

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

```csharp
await channelClient.RejectInviteAsync("<channel-type>", "<channel-id>", "thierry");
```

</codetabs-item>

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

```python
channel.reject_invite("thierry")
```

</codetabs-item>

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

```ruby
channel.reject_invite("thierry")
```

</codetabs-item>

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

```go
channel.RejectInvite(ctx, "thierry", nil)
```

</codetabs-item>

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

```java
// Android SDK
channelClient.rejectInvite().enqueue(result -> {
  if (result.isSuccess()) {
    // Invite rejected
  } else {
    // Handle result.error()
  }
});

// Backend SDK
Channel.update("messaging", "general")
  .acceptInvite(false)
  .userId("nick")
  .request();
```

</codetabs-item>

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

```csharp
await channel.RejectInviteAsync();
```

</codetabs-item>

</codetabs>

### Query for Accepted Invites

Querying for accepted invites is done via the `queryChannels` method. This allows you to return a list of accepted invites with a single call. See below for an example:

<codetabs>

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

```kotlin
val request = QueryChannelsRequest(
  filter = Filters.eq("invite", "accepted"),
  offset = 0,
  limit = 10
)
client.queryChannels(request).enqueue { result ->
  if (result is Result.Success) {
    val channels: List<Channel> = result.value
  } else {
    // Handle Result.Failure
  }
}
```

</codetabs-item>

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

```js
const invites = await client.queryChannels({
  invite: "accepted",
});

//server side (query invites for user rob)
const invites = await client.queryChannels(
  {
    invite: "accepted",
  },
  {},
  { user_id: "rob" },
);
```

</codetabs-item>

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

```php
$invites = $client->queryChannels(['invite' => 'accepted'],[], ['user_id' => 'jenny']);
```

</codetabs-item>

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

```dart
final invites = await client.queryChannels(filter: {"invite": "accepted"});
```

</codetabs-item>

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

```swift
import StreamChat

let controller = chatClient.channelListController(
  query: .init(
    filter: .equal(.invite, to: .accepted)
  )
)

controller.synchronize { error in
  if let error = error {
    // handle error
    print(error)
  } else {
    // access channels
    print(controller.channels)

    // load more if needed
    controller.loadNextChannels(limit: 10) { _ in
      // handle error / access channels
    }
  }
}
```

</codetabs-item>

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

```cpp
Client->QueryChannels(FFilter::Equal(TEXT("invite"), TEXT("accepted")));
```

</codetabs-item>

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

```csharp
await channelClient.QueryChannelsAsync(QueryChannelsOptions.Default.WithFilter(new Dictionary<string, object>
{
  { "invite", "accepted" },
}));
```

</codetabs-item>

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

```python
client.query_channels({"invite": "accepted"})
```

</codetabs-item>

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

```ruby
client.query_channels({ 'invite' => 'accepted' })
```

</codetabs-item>

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

```go
client.QueryChannels(ctx, &QueryOption{
	Filter: map[string]interface{}{
		"invite": "accepted",
	},
})
```

</codetabs-item>

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

```java
// Android SDK
FilterObject filter = Filters.eq("invite", "accepted");
int offset = 0;
int limit = 10;
QuerySorter<Channel> sort = new QuerySortByField<>();
int messageLimit = 0;
int memberLimit = 0;
QueryChannelsRequest request = new QueryChannelsRequest(filter, offset, limit, sort, messageLimit, memberLimit);

client.queryChannels(request).enqueue(result -> {
  if (result.isSuccess()) {
    List<Channel> channels = result.data();
  } else {
    // Handle result.error()
  }
});

// Backend SDK
Channel.queryMembers().type("messaging").id("general").filterCondition("invite", "accepted").request();
```

</codetabs-item>

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

```csharp
var filter = new List<IFieldFilterRule>
{
  ChannelFilter.Invite.EqualsTo(ChannelFieldInvite.Status.Accepted)
};

var sort = ChannelSort.OrderByDescending(ChannelSortFieldName.LastMessageAt);

var acceptedInvites = await Client.QueryChannelsAsync(filter, sort);
```

</codetabs-item>

</codetabs>

### Query for Rejected Invites

Similar to querying for accepted invites, you can query for rejected invites with `queryChannels` . See below for an example:

<codetabs>

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

```kotlin
val request = QueryChannelsRequest(
  filter = Filters.eq("invite", "rejected"),
  offset = 0,
  limit = 10
)
client.queryChannels(request).enqueue { result ->
  if (result is Result.Success) {
    val channels: List<Channel> = result.value
  } else {
    // Handle Result.Failure
  }
}
```

</codetabs-item>

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

```js
const rejected = client.queryChannels({
  invite: "rejected",
});

//server side (query invites for user rob)
const invites = await client.queryChannels(
  {
    invite: "rejected",
  },
  {},
  { user_id: "rob" },
);
```

</codetabs-item>

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

```php
$invites = $client->queryChannels(['invite' => 'rejected'],[], ['user_id' => 'jenny']);
```

</codetabs-item>

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

```dart
final rejected = await client.queryChannels(filter: {"invite": "rejected"});
```

</codetabs-item>

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

```swift
import StreamChat

let controller = chatClient.channelListController(
  query: .init(
    filter: .equal(.invite, to: .rejected)
  )
)

controller.synchronize { error in
  if let error = error {
    // handle error
    print(error)
  } else {
    // access channels
    print(controller.channels)

    // load more if needed
    controller.loadNextChannels(limit: 10) { _ in
      // handle error / access channels
    }
  }
}
```

</codetabs-item>

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

```cpp
Client->QueryChannels(FFilter::Equal(TEXT("invite"), TEXT("rejected")));
```

</codetabs-item>

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

```csharp
await channelClient.QueryChannelsAsync(QueryChannelsOptions.Default.WithFilter(new Dictionary<string, object>
{
  { "invite", "rejected" },
}));
```

</codetabs-item>

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

```python
client.query_channels({"invite": "rejected"})
```

</codetabs-item>

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

```ruby
client.query_channels({ 'invite' => 'rejected' })
```

</codetabs-item>

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

```go
client.QueryChannels(ctx, &QueryOption{
	Filter: map[string]interface{}{
		"invite": "rejected",
	},
})
```

</codetabs-item>

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

```java
// Andoid SDK
FilterObject filter = Filters.eq("invite", "rejected");
int offset = 0;
int limit = 10;
QuerySorter<Channel> sort = new QuerySortByField<>();
int messageLimit = 0;
int memberLimit = 0;
QueryChannelsRequest request = new QueryChannelsRequest(filter, offset, limit, sort, messageLimit, memberLimit);

client.queryChannels(request).enqueue(result -> {
  if (result.isSuccess()) {
    List<Channel> channels = result.data();
  } else {
    // Handle result.error()
  }
});

// Backend SDK
Channel.queryMembers()
  .type("messaging")
  .id("general")
  .filterCondition("invite", "rejected")
  .request();
```

</codetabs-item>

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

```csharp
var filter = new List<IFieldFilterRule>
{
  ChannelFilter.Invite.EqualsTo(ChannelFieldInvite.Status.Rejected)
};

var sort = ChannelSort.OrderByDescending(ChannelSortFieldName.LastMessageAt);

var rejectedInvites = await Client.QueryChannelsAsync(filter, sort);
```

</codetabs-item>

</codetabs>

### Query for Pending Invites

Similar to querying for accepted and rejected invites, you can query for pending invites with `queryChannels` . See below for an example:

<codetabs>

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

```kotlin
val request = QueryChannelsRequest(
  filter = Filters.eq("invite", "pending"),
  offset = 0,
  limit = 10
)
client.queryChannels(request).enqueue { result ->
  if (result is Result.Success) {
    val channels: List<Channel> = result.value
  } else {
    // Handle Result.Failure
  }
}
```

</codetabs-item>

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

```js
const rejected = client.queryChannels({
  invite: "pending",
});

//server side (query invites for user rob)
const invites = await client.queryChannels(
  {
    invite: "pending",
  },
  {},
  { user_id: "rob" },
);
```

</codetabs-item>

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

```php
$invites = $client->queryChannels(['invite' => 'pending'],[], ['user_id' => 'jenny']);
```

</codetabs-item>

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

```dart
final rejected = await client.queryChannels(filter: {"invite": "pending"});
```

</codetabs-item>

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

```swift
import StreamChat

let controller = chatClient.channelListController(
  query: .init(
    filter: .equal(.invite, to: .pending)
  )
)

controller.synchronize { error in
  if let error = error {
    // handle error
    print(error)
  } else {
    // access channels
    print(controller.channels)

    // load more if needed
    controller.loadNextChannels(limit: 10) { _ in
      // handle error / access channels
    }
  }
}
```

</codetabs-item>

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

```cpp
Client->QueryChannels(FFilter::Equal(TEXT("invite"), TEXT("pending")));
```

</codetabs-item>

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

```csharp
await channelClient.QueryChannelsAsync(QueryChannelsOptions.Default.WithFilter(new Dictionary<string, object>
{
  { "invite", "pending" },
}));
```

</codetabs-item>

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

```python
client.query_channels({"invite": "pending"})
```

</codetabs-item>

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

```ruby
client.query_channels({ 'invite' => 'pending' })
```

</codetabs-item>

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

```go
client.QueryChannels(ctx, &QueryOption{
	Filter: map[string]interface{}{
		"invite": "pending",
	},
})
```

</codetabs-item>

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

```java
FilterObject filter = Filters.eq("invite", "pending");
int offset = 0;
int limit = 10;
QuerySorter<Channel> sort = new QuerySortByField<>();
int messageLimit = 0;
int memberLimit = 0;
QueryChannelsRequest request = new QueryChannelsRequest(filter, offset, limit, sort, messageLimit, memberLimit);

client.queryChannels(request).enqueue(result -> {
  if (result.isSuccess()) {
    List<Channel> channels = result.data();
  } else {
    // Handle result.error()
  }
});
```

</codetabs-item>

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

```csharp
var filter = new List<IFieldFilterRule>
{
  ChannelFilter.Invite.EqualsTo(ChannelFieldInvite.Status.Pending)
};

var sort = ChannelSort.OrderByDescending(ChannelSortFieldName.LastMessageAt);

var pendingInvites = await Client.QueryChannelsAsync(filter, sort);
```

</codetabs-item>

</codetabs>

---

This page was last updated at 2025-08-15T14:14:35.683Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/ios-swift/channel_invites/](https://getstream.io/chat/docs/ios-swift/channel_invites/).