# POST /v1/content/:containerId/reject (/docs/api/reference/approval/reject-content)



<Endpoint method="POST" path="/v1/content/:containerId/reject" scope="content:approve" phase="1" />

Flips `approvalStatus` to `rejected` and stamps the reviewer. Rejected containers can't be scheduled. If you want a new take, call [`regenerate`](/docs/api/reference/content/regenerate-content) separately — this endpoint does not kick off a regeneration.

## Path parameters [#path-parameters]

<Parameters
  rows="[
  { name: 'containerId', type: 'string (uuid)', required: true, description: 'The container to reject.' },
]"
/>

## Body [#body]

<Parameters
  title="Body"
  rows="[
  { name: 'reason', type: 'string', required: true, description: 'Rejection note, 1–1024 chars. Stored on the container for audit.' },
]"
/>

## Request [#request]

<Tabs items="['curl', 'TypeScript', 'Python']">
  <Tab value="curl">
    ```sh title="terminal"
    curl -X POST https://api.layers.com/v1/content/{containerId}/reject \
      -H "X-Api-Key: $LAYERS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "reason": "Hook is off-brand; want something punchier." }'
    ```
  </Tab>

  <Tab value="TypeScript">
    ```ts title="reject.ts"
    const res = await fetch(
      `https://api.layers.com/v1/content/${containerId}/reject`,
      {
        method: 'POST',
        headers: {
          'X-Api-Key': process.env.LAYERS_API_KEY!,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ reason: 'Needs a new angle.' }),
      },
    );
    const result = await res.json();
    ```
  </Tab>

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

    r = httpx.post(
        f"https://api.layers.com/v1/content/{container_id}/reject",
        headers={
            "X-Api-Key": os.environ["LAYERS_API_KEY"],
            "Content-Type": "application/json",
        },
        json={"reason": "Off-brand hook."},
    )
    result = r.json()
    ```
  </Tab>
</Tabs>

## Responses [#responses]

<Response status="200" description="Rejected.">
  ```json
  {
    "id": "cnt_01HXZ9...",
    "approvalStatus": "rejected",
    "rejectedAt": "2026-04-18T09:44:50Z",
    "rejectedBy": "api_key_c2037bb9...",
    "reason": "Hook is off-brand; want something punchier."
  }
  ```
</Response>

<Response status="409" description="Container is already rejected or approved.">
  ```json
  {
    "error": {
      "code": "CONFLICT",
      "message": "Container is already rejected.",
      "requestId": "req_...",
      "details": { "approvalStatus": "rejected" }
    }
  }
  ```
</Response>

## Notes [#notes]

* **Approved → rejected isn't supported.** Once a container is `approved`, rejecting it is a `CONFLICT`. If approved content is wrong, cancel any scheduled posts and regenerate.
* **The first-N counter doesn't decrement on rejection.** Rejection is "this specific container didn't pass review", not "undo an approval". The counter is about building trust over time.
* **To produce a new take**, call [`regenerate`](/docs/api/reference/content/regenerate-content) with an updated brief.

## Errors [#errors]

| Code                | When                                              |
| ------------------- | ------------------------------------------------- |
| `CONFLICT`          | Container is already rejected or approved.        |
| `VALIDATION_FAILED` | Container isn't `completed`; or missing `reason`. |
| `NOT_FOUND`         | Container id not in this org.                     |
| `FORBIDDEN_SCOPE`   | Key lacks `content:approve`.                      |

## See also [#see-also]

* [Approve a container](/docs/api/reference/approval/approve-content)
* [Regenerate in place](/docs/api/reference/content/regenerate-content)
* [The approval policy](/docs/api/reference/approval/get-approval-policy)
