# GET /v1/projects/:projectId/approval-policy (/docs/api/reference/approval/get-approval-policy)



<Endpoint method="GET" path="/v1/projects/:projectId/approval-policy" scope="content:read" phase="1" />

Returns the approval policy on a project: whether new containers need human sign-off before scheduling, how many posts must pass review before the gate lifts, and how long auto-approval should wait. Read this once on project load to decide whether your UI should route new content through a review queue.

The policy is per-project, not per-org. Two projects on the same org can run different gates — one locked down with a five-post warmup, another wide open.

## Path parameters [#path-parameters]

<Parameters
  rows="[
  { name: 'projectId', type: 'string (uuid)', required: true, description: 'Project to read the policy for.' },
]"
/>

## Request [#request]

<Tabs items="['curl', 'TypeScript', 'Python']">
  <Tab value="curl">
    ```sh title="terminal"
    curl https://api.layers.com/v1/projects/{projectId}/approval-policy \
      -H "Authorization: Bearer $LAYERS_API_KEY"
    ```
  </Tab>

  <Tab value="TypeScript">
    ```ts title="approval-policy.ts"
    const res = await fetch(
      `https://api.layers.com/v1/projects/${projectId}/approval-policy`,
      { headers: { Authorization: `Bearer ${process.env.LAYERS_API_KEY!}` } },
    );
    const policy = await res.json();
    if (policy.requiresApproval) {
      // route new containers through the review queue
    }
    ```
  </Tab>

  <Tab value="Python">
    ```py title="approval_policy.py"
    import os, httpx

    r = httpx.get(
        f"https://api.layers.com/v1/projects/{project_id}/approval-policy",
        headers={"Authorization": f"Bearer {os.environ['LAYERS_API_KEY']}"},
    )
    policy = r.json()
    ```
  </Tab>
</Tabs>

## Responses [#responses]

<Response status="200" description="Gate is on with a first-5 warmup and 24-hour auto-approve fallback.">
  ```json
  {
    "projectId": "01HX9Y7K8M2P4RSTUV56789AB",
    "requiresApproval": true,
    "firstNPostsBlocked": 5,
    "autoApproveAfter": "PT24H",
    "updatedAt": "2026-04-10T12:00:00Z"
  }
  ```
</Response>

<Response status="200" description="No gate on this project.">
  ```json
  {
    "projectId": "01HX9Y7K8M2P4RSTUV56789AB",
    "requiresApproval": false,
    "firstNPostsBlocked": 0,
    "autoApproveAfter": null,
    "updatedAt": "2026-04-10T12:00:00Z"
  }
  ```
</Response>

## Field semantics [#field-semantics]

* **`requiresApproval`** — master switch. When `true`, newly generated containers land in `approvalStatus: "pending"` and [`schedule`](/docs/api/reference/publishing/schedule-content) refuses them until approved.
* **`firstNPostsBlocked`** — how many approvals a project must land before the gate lifts. Once this many containers are approved, subsequent containers default to `not_required` even with `requiresApproval: true`.
* **`autoApproveAfter`** — ISO-8601 duration (e.g. `PT24H`, `P7D`). If set, pending containers auto-approve after this duration has elapsed since their `createdAt`. Omit or pass `null` to disable auto-approval.

## Errors [#errors]

| Status | Code              | When                        |
| ------ | ----------------- | --------------------------- |
| 401    | `UNAUTHENTICATED` | Missing or invalid key.     |
| 403    | `FORBIDDEN_SCOPE` | Key lacks `content:read`.   |
| 404    | `NOT_FOUND`       | Project id not in this org. |
| 429    | `RATE_LIMITED`    | Read budget exhausted.      |

## See also [#see-also]

* [Change the policy](/docs/api/reference/approval/patch-approval-policy)
* [Approve a container](/docs/api/reference/approval/approve-content)
* [Schedule approved content](/docs/api/reference/publishing/schedule-content)
