---
title: "Approve or reject the posts on a reviewer's task list"
method: PUT
path: "/v2/scheduler/tasks/{userId}/approvals"
tags: ["Approval Task Api Service"]
---

# Approve or reject the posts on a reviewer's task list

`PUT /v2/scheduler/tasks/{userId}/approvals`

## Request

- Base URL: `https://app.metricool.com/api`
- URL: `https://app.metricool.com/api/v2/scheduler/tasks/{userId}/approvals`
- Auth: none declared

Authenticated. Records this reviewer's approve/reject decision on one or more of the posts waiting for them — one target or many, same contract — and returns a per-post result. The targets may span several brands: each brand is authorized on its own, and the caller must be allowed to approve posts (or hold full planner access) on it. Applied best-effort: a post that is not in the reviewer's set, is no longer actionable, or sits in a brand the caller may no longer approve on is reported as a failed result, not a 4xx. NOT_FOUND, NOT_ACTIONABLE and FORBIDDEN are terminal; ERROR is transient and retryable. An empty post list, more than 100 posts, a target missing its brand or post id, or a status other than 'approved' or 'rejected', is a 400 naming the offending field: a malformed list is rejected rather than partly acted on, so a decision is never applied to only part of what was sent. Repeated posts count once. The note is used only when rejecting.

## Path parameters

- `userId` integer, required

## Request body

- ApprovalTasksDecisionRequest: A reviewer's approve/reject decision applied to one or more of their tasks, possibly across several brands.
  - `posts` ApprovalTaskDecisionTarget[], required: The posts to decide on. One target for a single action, several for bulk. At most 100 targets per call: a longer list is rejected with a 400 rather than truncated, so a decision is never applied to only part of what was sent. A target missing its brand or post id is rejected the same way, for the same reason.
    - `blogId` integer, required: Id of the brand the post belongs to.
    - `postId` integer, required: Id of the post.
  - `status` 'approved' | 'rejected', required: The decision, applied to every listed post.
  - `note` string: Optional note; used only when rejecting. Attached as a post note and included in the rejection email to each post's creator.

## Response `200`

OK

- JsonOkResponseReviewerPostsDecisionResponse
  - `metadata` object
  - `page` JsonPaging
    - `next` string
  - `data` ReviewerPostsDecisionResponse: Per-post outcomes of a reviewer's approve/reject action, one entry per requested post.
    - `results` ReviewerPostDecisionResult[]: One result per requested post, in request order.
      - `postId` integer: The post this result refers to.
      - `reviewerStatus` 'approved' | 'rejected': This reviewer's new decision on the post.
      - `postApprovalStatus` string: Recomputed post-level approval status after this decision. Informational; normally present on success, absent only if the post was removed or the re-read failed.
      - `error` 'NOT_FOUND' | 'NOT_ACTIONABLE' | 'FORBIDDEN' | 'ERROR': Failure reason when the decision was not applied to a post. NOT_FOUND, NOT_ACTIONABLE and FORBIDDEN are terminal; ERROR is transient and retryable.

---

[API](https://skmtc.dev/metricool/apis/metricool-api.md) · [All operations](https://skmtc.dev/metricool/apis/metricool-api/llms.txt) · [OpenAPI document](https://skmtc.dev/metricool/apis/metricool-api/revisions/cd0ca612fa01?raw)
