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

# Flag and Unflag Users

> Flag users, remove your flag, and check user flag state with social.plus SDK.

Use user flagging when a member reports another user for moderator review. Flagging does not block, ban, or delete the user; it records reporting state that moderation workflows can review.

You can send a simple flag (just the `userId`) or an optional **structured report** that describes *what* is being reported and *why* — see [Add a report type, reason, and comment](#add-a-report-type-reason-and-comment-optional).

> [!NOTE]
>
> Flutter exposes flag and unflag actions from an `AmityUser` object.
> TypeScript, iOS, and Android expose repository methods that take a `userId`.

> [!NOTE]
>
> The structured report fields (`reportType`, `reason`, `comment`) are
> **optional** and **backward compatible**. A flag call with no report fields
> behaves exactly as before. These fields are recorded for moderators and are
> **not** returned in the API response.

## Parameters

| Operation | Required inputs | Platforms | Result shape |
| - | - | - | - |
| Flag user | `userId` (optional: `reportType`, `reason`, `comment`) | TypeScript, iOS, Android | TypeScript returns `Promise<Amity.User>`; iOS async call throws on failure; Android returns `Completable`. |
| Flag user | `AmityUser` object | Flutter | Returns `Future<AmityUser>`. |
| Unflag user | `userId` | TypeScript, iOS, Android | TypeScript returns `Promise<boolean>`; iOS async call throws on failure; Android returns `Completable`. |
| Unflag user | `AmityUser` object | Flutter | Returns `Future<AmityUser>`. |
| Check flag status | `userId` or `AmityUser` object | TypeScript, iOS, Android, Flutter | Boolean flag state where the platform exposes it. |

## Flag a user

Call the flag API when the current user reports another user.

### Inputs

| Platform | Method | Required inputs | Result shape |
| - | - | - | - |
| TypeScript | `UserRepository.flagUser(userId, options?)` | `userId` (optional `reportType`, `reason`, `comment`) | Returns `Promise<Amity.User>` — the flagged user. |
| iOS | `userRepository.flagUser(withId:reportType:reason:comment:)` | `userId` (optional `reportType`, `reason`, `comment`) | Async call that throws on failure. |
| Android | `userRepository.flagUser(userId, reportType?, reason?, comment?)` | `userId` (optional `reportType`, `reason`, `comment`) | Returns `Completable`. |
| Flutter | `user.report().flag()` | `AmityUser` object | Returns `Future<AmityUser>`. |

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

async function flagUser(userId: string) {
const flagged = await UserRepository.flagUser(userId);
console.log('Flagged:', flagged);
}

```

```swift iOS theme={null}
func flagUser() async {
    do {
        try await userRepository.flagUser(withId: "<user-id>")
        print("User flagged")
    } catch {
        print("Flag failed: \(error)")
    }
}
```

```kotlin Android theme={null}
fun flagUser(userRepository: AmityUserRepository, userId: String) {
    userRepository.flagUser(userId = userId)
        .doOnComplete {
            Log.d("UserFlag", "User flagged")
        }
        .doOnError { error ->
            Log.e("UserFlag", "Flag failed", error)
        }
        .subscribe()
}
```

```dart Flutter theme={null}
Future<void> flagUser(AmityUser user) async {
  try {
    final updatedUser = await user.report().flag();
    print('Flagged user: ${updatedUser.userId}');
  } on AmityException catch (error) {
    print('Flag failed: ${error.message}');
  }
}
```

## Add a report type, reason, and comment (optional)

When you want moderators to know *what* part of a profile is being reported and *why*, attach one or more optional fields to the flag call.

| Field | Answers | Description |
| - | - | - |
| `reportType` | **What** | The aspect of the profile being reported. One of `displayName`, `description`, `avatarFileId`, or `behavior`. Omit it for a generic (typeless) report. |
| `reason` | **Why** | A predefined reason for a `behavior` report. **Required** when `reportType` is `behavior`, and not allowed with any other type. |
| `comment` | **Detail** | Free-text context from the reporter (max 300 characters). Allowed with any report type, including a typeless report. |

### Report types

`reportType` uses fixed values; your app decides the label to show the member.

| Value | Suggested label | Reports the user's… |
| - | - | - |
| `displayName` | Username | display name |
| `description` | Bio | bio / description |
| `avatarFileId` | Avatar | profile image |
| `behavior` | Behavior | conduct (requires a `reason`) |

### Reasons

For a `behavior` report, pass a `reason` from the shared content report-reason list (the same values used when flagging posts, comments, and messages): `communityGuidelines`, `harassmentOrBullying`, `selfHarmOrSuicide`, `violenceOrThreateningContent`, `sellingRestrictedItems`, `sexualContentOrNudity`, `spamOrScams`, `falseInformation`, or `others` with a custom string.

### Rules

> [!NOTE]
>
> * `reason` is **required** when `reportType` is `behavior`, and **rejected** for every other type (and for typeless reports).
> * `reason` and `comment` are each capped at **300 characters**.
> * A member holds **one report per report type** on a target (up to four typed reports plus one typeless). Reporting the **same** type again updates that report; reporting a **different** type adds a new one.
> * Unflagging removes **all** of your reports on that user at once — there is no per-type unflag.
> * Breaking a rule returns a validation error (HTTP `422`) from the server.

### Examples

Pass the optional fields alongside the `userId`. Send `reason` only with a `behavior` report, and add a `comment` on any report type when the reporter provides extra detail.

```typescript TypeScript theme={null}
import { ContentFlagReasonEnum, UserReportTypeEnum, UserRepository } from '@amityco/ts-sdk';

// Report a user's behavior, with a reason and comment
await UserRepository.flagUser(userId, {
  reportType: UserReportTypeEnum.BEHAVIOR,
  reason: ContentFlagReasonEnum.SpamOrScams,
  comment: 'Repeatedly posting promo links',
});

// Report a profile field (no reason)
await UserRepository.flagUser(userId, { reportType: UserReportTypeEnum.AVATAR });
```

```swift iOS theme={null}
// Report a user's behavior, with a reason and comment
try await userRepository.flagUser(
    withId: "<user-id>",
    reportType: .behavior,
    reason: .spamOrScams,
    comment: "Repeatedly posting promo links"
)

// Report a profile field (no reason)
try await userRepository.flagUser(withId: "<user-id>", reportType: .avatarFileId)
```

```kotlin Android theme={null}
// Report a user's behavior, with a reason and comment
userRepository.flagUser(
    userId = userId,
    reportType = AmityUserReportType.BEHAVIOR,
    reason = AmityContentFlagReason.SpamOrScams,
    comment = "Repeatedly posting promo links"
).subscribe()

// Report a profile field (no reason)
userRepository.flagUser(
    userId = userId,
    reportType = AmityUserReportType.AVATAR
).subscribe()
```

> [!TIP]
>
> To report more than one aspect of the same profile (for example the avatar
> **and** the behavior), send a separate flag call for each `reportType`. They
> are stored as distinct reports.

## Unflag a user

Call the unflag API when the current user removes their report from another user.

### Inputs

| Platform | Method | Required inputs | Result shape |
| - | - | - | - |
| TypeScript | `UserRepository.unflagUser(userId)` | `userId` | Returns `Promise<boolean>`. |
| iOS | `userRepository.unflagUser(withId:)` | `userId` | Async call that throws on failure. |
| Android | `userRepository.unflagUser(userId)` | `userId` | Returns `Completable`. |
| Flutter | `user.report().unflag()` | `AmityUser` object | Returns `Future<AmityUser>`. |

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

async function unflagUser(userId: string) {
const unflagged = await UserRepository.unflagUser(userId);
console.log('Unflagged:', unflagged);
}

```

```swift iOS theme={null}
func unflagUser() async {
    do {
        try await userRepository.unflagUser(withId: "<user-id>")
        print("User unflagged")
    } catch {
        print("Unflag failed: \(error)")
    }
}
```

```kotlin Android theme={null}
fun unflagUser(userRepository: AmityUserRepository, userId: String) {
    userRepository.unflagUser(userId = userId)
        .doOnComplete {
            Log.d("UserFlag", "User unflagged")
        }
        .doOnError { error ->
            Log.e("UserFlag", "Unflag failed", error)
        }
        .subscribe()
}
```

```dart Flutter theme={null}
Future<void> unflagUser(AmityUser user) async {
  try {
    final updatedUser = await user.report().unflag();
    print('Unflagged user: ${updatedUser.userId}');
  } on AmityException catch (error) {
    print('Unflag failed: ${error.message}');
  }
}
```

## Check whether the current user flagged a user

Use the flag-state API or property to decide whether to show a flag or unflag action.

### Inputs

| Platform | Method | Required inputs | Result shape |
| - | - | - | - |
| TypeScript | `UserRepository.isUserFlaggedByMe(userId)` | `userId` | Returns `Promise<boolean>`. |
| iOS | `userRepository.isUserFlaggedByMe(withId:)` | `userId` | Returns `Bool` from an async call. |
| Android | `user.isFlaggedByMe()` | `AmityUser` object | Returns `Boolean` from the loaded user model. |
| Flutter | `user.isFlaggedByMe` | `AmityUser` object | Returns `bool` from the loaded user model. |

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

async function checkFlagState(userId: string) {
const isFlagged = await UserRepository.isUserFlaggedByMe(userId);
console.log('Flagged by me:', isFlagged);
}

```

```swift iOS theme={null}
func checkFlagState() async {
    do {
        let isFlagged = try await userRepository.isUserFlaggedByMe(withId: "<user-id>")
        print("Flagged by me: \(isFlagged)")
    } catch {
        print("Flag-state check failed: \(error)")
    }
}
```

```kotlin Android theme={null}
fun checkFlagState(user: AmityUser) {
    val isFlaggedByMe = user.isFlaggedByMe()
    val totalFlagCount = user.getFlagCount()
    Log.d("UserFlag", "Flagged by me: $isFlaggedByMe, total: $totalFlagCount")
}
```

```dart Flutter theme={null}
void checkFlagState(AmityUser user) {
  final isFlaggedByMe = user.isFlaggedByMe;
  print('Flagged by me: $isFlaggedByMe');
}
```

## Platform notes

* Flagging is a report signal for moderation review; it does not automatically block, ban, or delete the user.
* TypeScript, iOS, and Android flag by `userId`.
* Flutter flags through the loaded `AmityUser` object.
* Android and Flutter expose flag status from the loaded user model.

## Related topics

> **[Get User Information](/social-plus-sdk/core-concepts/user-management/user-operations/get-user-information.md)**
>
> Retrieve user details and flag status.

> **[Roles and Permissions](/social-plus-sdk/core-concepts/user-management/roles-permissions.md)**
>
> Gate moderation actions with permission checks.


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