> ## 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.

# Join/Leave Community

> Join or leave communities, handle join requests, and manage approval flows

Use community membership APIs to let the active user join or leave a community. Communities that require approval return a pending join request instead of immediate membership.

<Info>
  iOS, Android, and TypeScript support object-based `community.join()` flows that return a success or pending result. Flutter currently exposes repository-level `joinCommunity()` and `leaveCommunity()` methods.
</Info>

## Parameters

| Operation                     | Parameter           | Required           | Description                                                               |
| ----------------------------- | ------------------- | ------------------ | ------------------------------------------------------------------------- |
| Join community                | Community object    | Platform-dependent | iOS, Android, and TypeScript call `join()` on a fetched community object. |
| Join community                | `communityId`       | Platform-dependent | Flutter joins by community ID.                                            |
| Check my join request         | Community object    | Yes                | Fetched community object used to read the active user's pending request.  |
| Observe pending join requests | Community object    | Yes                | Fetched community object used by moderators to list join requests.        |
| Observe pending join requests | `status` / `limit`  | No                 | Optional request status and page-size controls where exposed.             |
| Cancel, approve, or reject    | Join request object | Yes                | Join request object returned from a join-request query.                   |
| Leave community               | `communityId`       | Yes                | Community ID the active user should leave.                                |

## Join Community

For approval-aware flows, fetch a community object first and call `join()` where the platform supports it. The result tells you whether membership was granted immediately or a join request is pending.

<CodeGroup>
  ```swift iOS theme={null}
  var community: AmityCommunity! // Fetched community

  Task { @MainActor in
      do {
          let result = try await community.join()

          switch result {
          case .success:
              // Joined immediately
              break
          case .pending(let joinRequest):
              let status = joinRequest.status
              // Show pending state
          }
      } catch let error {
          handleError(error)
      }
  }
  ```

  ```kotlin Android theme={null}
  fun joinCommunity(community: AmityCommunity) {
      community.join()
          .doOnSuccess { result ->
              when (result) {
                  is AmityJoinResult.Success -> {
                      // Joined immediately
                  }
                  is AmityJoinResult.Pending -> {
                      val joinRequest = result.request
                      // Show pending state
                  }
              }
          }
          .doOnError { throwable ->
              when (AmityError.from(throwable)) {
                  AmityError.ITEM_NOT_FOUND -> {
                      // Community does not exist
                  }
                  AmityError.USER_IS_BANNED -> {
                      // Current user is banned
                  }
                  else -> {
                      // Handle other errors
                  }
              }
          }
          .subscribe()
  }
  ```

  ```typescript TypeScript theme={null}
  async function joinCommunity(community: Amity.Community): Promise<Amity.JoinResult> {
    const result = await community.join();

    if (result.status === 'pending') {
      const joinRequest = result.request;
      // Show pending state
    }

    return result;
  }
  ```

  ```dart Flutter theme={null}
  Future<void> joinCommunity(String communityId) async {
    await AmitySocialClient.newCommunityRepository()
        .joinCommunity(communityId);
  }
  ```
</CodeGroup>

## Join Requests

When a community requires approval, the SDK exposes the active user's request and moderator review flows.

### Check My Join Request

Fetch the active user's join request when an approval-required community returns a pending state.

<CodeGroup>
  ```swift iOS theme={null}
  var community: AmityCommunity! // Fetched community

  Task { @MainActor in
      do {
          let joinRequest = try await community.getMyJoinRequest()
          let status = joinRequest.status
          // Render status
      } catch let error {
          handleError(error)
      }
  }
  ```

  ```kotlin Android theme={null}
  fun getMyJoinRequest(community: AmityCommunity) {
      community.getMyJoinRequest()
          .doOnSuccess { joinRequest ->
              val status = joinRequest.getStatus()
              // Render status
          }
          .doOnError { throwable ->
              // Handle error
          }
          .subscribe()
  }
  ```

  ```typescript TypeScript theme={null}
  async function getMyJoinRequest(community: Amity.Community) {
    const joinRequest = await community.getMyJoinRequest();

    if (joinRequest?.status === 'pending') {
      // Render pending state
    }

    return joinRequest;
  }
  ```
</CodeGroup>

### Observe Pending Join Requests

Moderators can observe join requests for a community and approve or reject individual requests.

<CodeGroup>
  ```swift iOS theme={null}
  var community: AmityCommunity! // Fetched community

  token = community.getJoinRequests(status: .pending).observe { collection, error in
      if let error = error {
          handleError(error)
          return
      }

      let joinRequests = collection.snapshots
      // Render pending requests
  }
  ```

  ```kotlin Android theme={null}
  fun observePendingJoinRequests(community: AmityCommunity) {
      community.getJoinRequests(status = AmityJoinRequestStatus.PENDING)
          .doOnNext { joinRequests: PagingData<AmityJoinRequest> ->
              // Render pending requests
          }
          .doOnError { throwable ->
              // Handle error
          }
          .subscribe()
  }
  ```

  ```typescript TypeScript theme={null}
  import { JoinRequestStatusEnum } from '@amityco/ts-sdk';

  function observePendingJoinRequests(community: Amity.Community) {
    return community.getJoinRequests(
      {
        communityId: community.communityId,
        type: 'communityJoinRequest',
        targetType: 'community',
        status: JoinRequestStatusEnum.Pending,
        options: { limit: 20 },
      },
      ({ data: joinRequests, loading, error }) => {
        if (error) {
          // Handle error
          return;
        }

        if (!loading && joinRequests) {
          // Render pending requests
        }
      },
    );
  }
  ```
</CodeGroup>

### Cancel, Approve, or Reject

Cancel your own request or approve and reject pending requests from a moderator flow.

<CodeGroup>
  ```swift iOS theme={null}
  func cancelJoinRequest(_ joinRequest: AmityJoinRequest) {
      Task { @MainActor in
          do {
              try await joinRequest.cancel()
          } catch let error {
              handleError(error)
          }
      }
  }

  func approveJoinRequest(_ joinRequest: AmityJoinRequest) {
      Task { @MainActor in
          do {
              try await joinRequest.approve()
          } catch let error {
              handleError(error)
          }
      }
  }

  func rejectJoinRequest(_ joinRequest: AmityJoinRequest) {
      Task { @MainActor in
          do {
              try await joinRequest.reject()
          } catch let error {
              handleError(error)
          }
      }
  }
  ```

  ```kotlin Android theme={null}
  fun cancelJoinRequest(joinRequest: AmityJoinRequest) {
      joinRequest.cancel()
          .doOnComplete {
              // Cancelled
          }
          .subscribe()
  }

  fun approveJoinRequest(joinRequest: AmityJoinRequest) {
      joinRequest.approve()
          .doOnComplete {
              // Approved
          }
          .subscribe()
  }

  fun rejectJoinRequest(joinRequest: AmityJoinRequest) {
      joinRequest.reject()
          .doOnComplete {
              // Rejected
          }
          .subscribe()
  }
  ```

  ```typescript TypeScript theme={null}
  async function cancelJoinRequest(joinRequest: Amity.JoinRequest) {
    await joinRequest.cancel();
  }

  async function approveJoinRequest(joinRequest: Amity.JoinRequest) {
    await joinRequest.approve();
  }

  async function rejectJoinRequest(joinRequest: Amity.JoinRequest) {
    await joinRequest.reject();
  }
  ```
</CodeGroup>

## Leave Community

Use `leaveCommunity()` to remove the active user from a community.

<Warning>
  Leaving removes the current user's community membership. If the community requires approval, the user may need to request access again before rejoining.
</Warning>

<CodeGroup>
  ```swift iOS theme={null}
  do {
      try await communityRepository.leaveCommunity(withId: communityId)
  } catch let error {
      handleError(error)
  }
  ```

  ```kotlin Android theme={null}
  fun leaveCommunity(communityRepository: AmityCommunityRepository, communityId: String) {
      communityRepository
          .leaveCommunity(communityId = communityId)
          .doOnComplete {
              // Left community
          }
          .doOnError { throwable ->
              when (AmityError.from(throwable)) {
                  AmityError.ITEM_NOT_FOUND -> {
                      // Community does not exist
                  }
                  AmityError.PERMISSION_DENIED -> {
                      // Permission denied
                  }
                  else -> {
                      // Handle other errors
                  }
              }
          }
          .subscribe()
  }
  ```

  ```typescript TypeScript theme={null}
  import { CommunityRepository } from '@amityco/ts-sdk';

  async function leaveCommunity(communityId: Amity.Community['communityId']) {
    const hasLeft = await CommunityRepository.leaveCommunity(communityId);
    return hasLeft;
  }
  ```

  ```dart Flutter theme={null}
  Future<void> leaveCommunity(String communityId) async {
    await AmitySocialClient.newCommunityRepository()
        .leaveCommunity(communityId);
  }
  ```
</CodeGroup>

## Related Topics

<CardGroup cols={2}>
  <Card title="Query Community Members" href="./query-community-members" icon="magnifying-glass">
    View and search community member lists.
  </Card>

  <Card title="Member Management" href="./member-management" icon="users-cog">
    Add and remove community members.
  </Card>

  <Card title="Community Moderation" href="./community-moderation" icon="shield-check">
    Manage roles, bans, and permissions.
  </Card>

  <Card title="Community Invitation" href="./community-invitation" icon="inbox-out">
    Invitation-based member onboarding workflows.
  </Card>
</CardGroup>
