# Content-review policy (/docs/api/reference/approval/policy)





The content-review policy controls whether generated content needs human approval before it can be scheduled or published. See the [Content review concept](/docs/api/concepts/content-review) for the full mental model.

## `GET /v1/projects/:projectId/content-review-policy` [#get-v1projectsprojectidcontent-review-policy]

Read the current policy + the live `pendingCount` (queue depth).

<Tabs items="['curl', 'fetch', 'Python requests']">
  <Tab value="curl">
    ```bash
    curl https://api.layers.com/v1/projects/$PROJECT_ID/content-review-policy \
      -H "Authorization: Bearer $LAYERS_API_KEY"
    ```
  </Tab>

  <Tab value="fetch">
    ```ts
    await fetch(
      `https://api.layers.com/v1/projects/${projectId}/content-review-policy`,
      { headers: { "Authorization": `Bearer ${process.env.LAYERS_API_KEY}` } },
    );
    ```
  </Tab>

  <Tab value="Python requests">
    ```python
    requests.get(
        f"https://api.layers.com/v1/projects/{project_id}/content-review-policy",
        headers={"Authorization": f"Bearer {os.environ['LAYERS_API_KEY']}"},
    )
    ```
  </Tab>
</Tabs>

### Response [#response]

```jsonc
{
  "projectId": "5e9c0b1e-…",
  "policy": "review_first_n",
  "firstN": 3,
  "pendingCount": 1,
  "updatedAt": "2026-04-25T22:55:10.996Z"
}
```

| Field          | Type                                                 | Notes                                                                                                          |
| -------------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `projectId`    | UUID                                                 | Echo of the path param.                                                                                        |
| `policy`       | `"auto_approve" \| "review_first_n" \| "review_all"` | The active mode.                                                                                               |
| `firstN`       | int (1–50)                                           | Present **only** when `policy === "review_first_n"`.                                                           |
| `pendingCount` | int ≥ 0                                              | Live count of containers on this project currently in `approvalStatus: "pending"`. Server-computed, read-only. |
| `updatedAt`    | ISO-8601                                             | Last `PATCH` timestamp. Absent if the policy has never been set (defaults to `auto_approve`).                  |

## `PATCH /v1/projects/:projectId/content-review-policy` [#patch-v1projectsprojectidcontent-review-policy]

Change the policy. Body is a discriminated union: `firstN` is **required** when `policy === "review_first_n"` and **forbidden** otherwise.

<Tabs items="['Switch on first-N gate', 'Require all', 'Auto-approve everything']">
  <Tab value="Switch on first-N gate">
    ```bash
    curl -X PATCH \
      "https://api.layers.com/v1/projects/$PROJECT_ID/content-review-policy" \
      -H "Authorization: Bearer $LAYERS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"policy":"review_first_n","firstN":5}'
    ```
  </Tab>

  <Tab value="Require all">
    ```bash
    curl -X PATCH \
      "https://api.layers.com/v1/projects/$PROJECT_ID/content-review-policy" \
      -H "Authorization: Bearer $LAYERS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"policy":"review_all"}'
    ```
  </Tab>

  <Tab value="Auto-approve everything">
    ```bash
    curl -X PATCH \
      "https://api.layers.com/v1/projects/$PROJECT_ID/content-review-policy" \
      -H "Authorization: Bearer $LAYERS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"policy":"auto_approve"}'
    ```
  </Tab>
</Tabs>

### Request body [#request-body]

| Field    | Type       | Required    | Notes                                                                         |
| -------- | ---------- | ----------- | ----------------------------------------------------------------------------- |
| `policy` | enum       | yes         | One of `auto_approve`, `review_first_n`, `review_all`.                        |
| `firstN` | int (1–50) | conditional | Required iff `policy === "review_first_n"`. Forbidden in the other two modes. |

### Response [#response-1]

The same shape as `GET`. `updatedAt` is set to the server time of the patch.

### Errors [#errors]

| Status / code    | When                                                               |
| ---------------- | ------------------------------------------------------------------ |
| `422 VALIDATION` | Missing `firstN` when `policy === "review_first_n"`.               |
| `422 VALIDATION` | `firstN` supplied when `policy` is `auto_approve` or `review_all`. |
| `422 VALIDATION` | `firstN` outside `[1, 50]`.                                        |
| `404 NOT_FOUND`  | Project does not belong to the calling org.                        |

## How it interacts with content generation [#how-it-interacts-with-content-generation]

When the API creates a `content_container` (via `POST /v1/projects/:id/content` or any other workflow that produces a container), it consults this policy:

* `auto_approve` → new container's `approvalStatus = "not_required"`.
* `review_all` → `approvalStatus = "pending"`.
* `review_first_n` → `approvalStatus = "pending"` if the project has fewer than `firstN` containers in a terminal review state (approved or rejected); otherwise `"not_required"`. The transition self-disables — once N have cleared, the project effectively becomes `auto_approve` for new containers.

Use [`POST /v1/content/:containerId/approve`](/docs/api/reference/approval/approve-content) and [reject](/docs/api/reference/approval/reject-content) to move pending containers through review.
