---
title: "Update site settings (visibility, slug, expiry, passcode, email gate, client space)."
method: PATCH
path: "/sites/{idOrSlug}"
tags: ["Sites"]
---

# Update site settings (visibility, slug, expiry, passcode, email gate, client space).

`PATCH /sites/{idOrSlug}`

## Request

- Base URL: `https://api.stacktr.ee`
- URL: `https://api.stacktr.ee/sites/{idOrSlug}`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.stacktr.ee/oauth/authorize`, token URL `https://api.stacktr.ee/oauth/token`, scopes: `sites:write`, `sites:read`)

JSON body. Only the fields you send are changed. Passcodes work on every plan (free covers its 3 pages); email gates start on Solo, so setting one on a free plan returns 402. Clearing either always works.

## Request body

- object
  - `title` string, nullable: Display name. Kept when the page is updated or a version restored: later content does not rename it (GET shows title_custom: true). null/empty goes back to the page's own <title>.
  - `description` string, nullable: The line under the name on a client portal and in link previews, up to 240 characters. Kept through updates like title (description_custom: true). null/empty goes back to the page's own description.
  - `public_slug` string, nullable: Publish at {slug}.stacktr.ee (public); null returns the page to unlisted.
  - `password` string, nullable: Set a passcode (paid plans), or null to clear.
  - `expires_in_hours` integer, nullable: Hours from now, or null for no expiry. A number over the plan ceiling is clamped to it and the response says so (`expiry_clamped: true`). null (no expiry) on a capped plan is REFUSED with 409 `expiry_clamped` and nothing in the PATCH is applied, so an agent cannot report a 7-day page as permanent; send `accept_clamp: true` alongside it to take the ceiling instead. The response carries the whole expiry block: `expires_at`, `expires_at_iso`, `ttl_seconds`, `expiry_clamped`, `expiry_ceiling_hours`, `expiry_source`.
  - `accept_clamp` boolean: Accept the plan ceiling when asking for a page that never expires, instead of being refused. Ignored for every other value of expires_in_hours.
  - `allowed_email_domain` string, nullable: Require visitors to verify an email: domains and/or single addresses separated by commas ("acme.com, jane@globex.com"), up to 20 (paid plans), or null to clear. Mutually exclusive with password.
  - `burn_after_read` boolean
  - `csp_strict` boolean
  - `disabled` boolean: true takes the page offline (link serves the expired page); false brings it back. Reversible — content, view history and share links are kept.
  - `agentation` boolean
  - `reactions` boolean
  - `ai_review` boolean: Let a reader hand the page to their own ChatGPT or Claude through a two-hour review link ("Review with your AI"). Off by default.
  - `ai_copy` boolean: On a page behind a passcode or an email check, a line at the foot lets the reader who got in copy the page as Markdown for their own assistant. On by default; false turns it off.
  - `client` string, nullable: File the site under a client space by name or slug (auto-created), or null to detach it to a floating page. Filing also derives a stable space_path for the page.

## Response `200`

Updated.

- object
  - `ok` boolean

## Other responses

- `402`: A plan ceiling was hit. The feature or the quota is not on this plan; the caller needs a different plan or an x402 unlock.
- `409`: The page cannot take this write in its current state. Read `error`: `site_deleted` means it has stopped serving and is being kept for 30 days: restore it with POST /sites/{idOrSlug}/restore and retry, and do NOT publish it again, which would create a second page at a different URL. `managed_portal` means it is a generated client portal that rebuilds from its space. `slug already taken` means another page holds that public slug, including a retired page still reserving it for its restore window.

---

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