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

# Post Review

> Approve, decline, and query posts in community review states with the public SDKs.

Use post review when a community requires posts to be approved before they appear in the published feed. The SDKs expose approval actions by post ID, plus query filters for building a review queue.

## Platform Support

| Platform   | Approve                               | Decline                               | Query review queue                                   |
| ---------- | ------------------------------------- | ------------------------------------- | ---------------------------------------------------- |
| TypeScript | `PostRepository.approvePost(postId)`  | `PostRepository.declinePost(postId)`  | `PostRepository.getPosts({ feedType: "reviewing" })` |
| iOS        | `postRepository.approvePost(withId:)` | `postRepository.declinePost(withId:)` | `AmityPostQueryOptions(feedType: .reviewing)`        |
| Android    | `postRepository.approvePost(postId)`  | `postRepository.declinePost(postId)`  | `.reviewStatus(AmityReviewStatus.UNDER_REVIEW)`      |
| Flutter    | `reviewPost(postId:).approve()`       | `reviewPost(postId:).decline()`       | `.feedType(AmityFeedType.REVIEWING)`                 |

<Info>
  TypeScript's current post query type exposes `published` and `reviewing` as live collection feed filters. Android, iOS, and Flutter expose published, reviewing, and declined states in their review/feed status models.
</Info>

## Parameters

| Operation            | Parameter                    | Required | Description                                                 |
| -------------------- | ---------------------------- | -------- | ----------------------------------------------------------- |
| Check review status  | Post object                  | Yes      | Loaded post object whose feed/review status should be read. |
| Approve or decline   | `postId`                     | Yes      | Post ID to approve or decline.                              |
| Query a review queue | `communityId`                | Yes      | Community whose reviewing posts should be listed.           |
| Query a review queue | Review/feed status           | Yes      | Reviewing/under-review filter for the target SDK.           |
| Query a review queue | Sort and pagination controls | No       | Optional collection controls exposed by the platform.       |

## Check Review Status

Read review status from a loaded post before deciding which moderation actions or labels to show.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const isPublished = post.feedType === "published";
  const isUnderReview = post.feedType === "reviewing";

  renderResults({ isPublished, isUnderReview });
  ```

  ```swift iOS theme={null}
  if let currentPost = postRepository.getPost(withId: "post-id").snapshot {
      switch currentPost.getFeedType() {
      case .published:
          showSuccessMessage("published")
      case .reviewing:
          showSuccessMessage("reviewing")
      case .declined:
          showSuccessMessage("declined")
      @unknown default:
          showSuccessMessage("unknown")
      }
  }
  ```

  ```kotlin Android theme={null}
  when (post?.getReviewStatus()) {
      AmityReviewStatus.PUBLISHED -> showSuccessMessage("published")
      AmityReviewStatus.UNDER_REVIEW -> showSuccessMessage("reviewing")
      AmityReviewStatus.DECLINED -> showSuccessMessage("declined")
      null -> showSuccessMessage("unknown")
  }
  ```

  ```dart Flutter theme={null}
  final post = await AmitySocialClient.newPostRepository().getPost(postId);

  switch (post.feedType) {
    case AmityFeedType.PUBLISHED:
      final status = 'published';
      break;
    case AmityFeedType.REVIEWING:
      final status = 'reviewing';
      break;
    case AmityFeedType.DECLINED:
      final status = 'declined';
      break;
    default:
      final status = 'unknown';
  }
  ```
</CodeGroup>

## Approve or Decline

Approve or decline by post ID after your product confirms the current user should moderate that community.

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

  const { data: approvedPost } = await PostRepository.approvePost(postId);
  const { data: declinedPost } = await PostRepository.declinePost(postId);

  renderResults([approvedPost, declinedPost]);
  ```

  ```swift iOS theme={null}
  try await postRepository.approvePost(withId: "post-id")
  try await postRepository.declinePost(withId: "post-id")

  showSuccessMessage()
  ```

  ```kotlin Android theme={null}
  postRepository.approvePost(postId = postId)
      .subscribe(
          { showSuccessMessage(postId) },
          { error -> handleGeneralError(error) }
      )

  postRepository.declinePost(postId = postId)
      .subscribe(
          { showSuccessMessage(postId) },
          { error -> handleGeneralError(error) }
      )
  ```

  ```dart Flutter theme={null}
  await AmitySocialClient.newPostRepository()
      .reviewPost(postId: postId)
      .approve();

  await AmitySocialClient.newPostRepository()
      .reviewPost(postId: postId)
      .decline();
  ```
</CodeGroup>

## Query a Review Queue

Query reviewing posts for a community when building a moderation queue.

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

  const unsubscribe = PostRepository.getPosts(
    {
      targetType: "community",
      targetId: communityId,
      feedType: "reviewing",
      sortBy: "lastCreated",
    },
    ({ data: posts, loading, error, onNextPage, hasNextPage }) => {
      if (loading) return;
      if (error) {
        handleError(error);
        return;
      }

      renderResults(posts);

      if (hasNextPage) {
        onNextPage?.();
      }
    },
  );
  ```

  ```swift iOS theme={null}
  let options = AmityPostQueryOptions(
      targetType: .community,
      targetId: communityId,
      sortBy: .lastCreated,
      deletedOption: .notDeleted,
      dataTypes: nil,
      feedType: .reviewing
  )

  token = postRepository.getPosts(options).observe { collection, error in
      showSuccessMessage(collection.snapshots.count)
  }
  ```

  ```kotlin Android theme={null}
  postRepository
      .getPosts()
      .targetCommunity(communityId = communityId)
      .reviewStatus(reviewStatus = AmityReviewStatus.UNDER_REVIEW)
      .build()
      .query()
      .subscribe(
          { pagingData -> showSuccessMessage(pagingData) },
          { error -> handleGeneralError(error) }
      )
  ```

  ```dart Flutter theme={null}
  final reviewQueue = AmitySocialClient.newPostRepository()
      .getPosts()
      .targetCommunity(communityId)
      .feedType(AmityFeedType.REVIEWING)
      .getLiveCollection(pageSize: 20);

  reviewQueue.getStreamController().stream.listen((posts) {
    final count = posts.length;
  });

  await reviewQueue.loadNext();
  ```
</CodeGroup>

## Notes

* Show approve and decline actions only to users who should moderate the community.
* Approval and decline calls operate by post ID and rely on backend permission checks.
* Remove reviewed posts from local review queues after successful action, or wait for the live collection to update.

## Related Topics

<CardGroup cols={3}>
  <Card title="Query Posts" icon="filter" href="../retrieval/query-posts">
    Query community feeds by review status.
  </Card>

  <Card title="Delete Posts" icon="trash" href="./delete-post">
    Remove posts during moderation.
  </Card>

  <Card title="Pinned Posts" icon="thumbtack" href="./pin-post">
    Display pinned posts.
  </Card>
</CardGroup>
