---
title: "Manage variants and page overrides"
method: POST
path: "/projects/{projectId}/hierarchy"
tags: ["Project structure"]
---

# Manage variants and page overrides

`POST /projects/{projectId}/hierarchy`

## Request

- Base URL: `https://studio.weaverse.io/api/v1/content`
- URL: `https://studio.weaverse.io/api/v1/content/projects/{projectId}/hierarchy`
- Auth: HTTP bearer

Runs one hierarchy operation, selected by `op`. A variant is a child project that inherits pages (and optionally the theme) from its parent; customizing a page gives the variant its own override. All operations take effect immediately.

Operations:

- `create-variant`: creates a variant of this project named `name` (1-100 characters), with optional `variantDescription` (max 500) and `inheritTheme` (default `true`). `contentStrategy` is `empty` (default; the variant inherits every page) or `clone-all` (copies every page into the variant). Returns `201` with the new project and `clonedPagesCount`.
- `link-parent`: makes this project a variant of `parentProjectId` (same shop), with optional `variantDescription` and `inheritTheme`. Hierarchies are at most two levels deep.
- `detach-parent` (`confirm` equal to the `projectId`): turns this variant into an independent project, copying inherited content first. Returns `pagesCopied`.
- `customize-page`: copies a page inherited from the parent into this variant as an override. `pageAssignmentId` is the parent's assignment id.
- `revert-page` (`content:delete`, `confirm` equal to `pageAssignmentId`): deletes this variant's override so the page inherits from the parent again. Only allowed when the parent would actually serve a live page for the override's exact market or locale; otherwise it returns `409 CONFLICT` and the override is kept.

A refused transition (maximum depth, project name already taken, circular link, not a variant, page already customized) returns `409 CONFLICT` and changes nothing. A wrong `confirm` value returns `400 INVALID_PARAMS`.

Required scope: `project:manage` (all operations); `revert-page` also needs `content:delete`

## Request body

- union
  - object
    - `op` 'create-variant', required
    - `name` string, required
    - `variantDescription` string
    - `inheritTheme` boolean
    - `contentStrategy` 'empty' | 'clone-all'
  - object
    - `op` 'link-parent', required
    - `parentProjectId` string, required
    - `variantDescription` string
    - `inheritTheme` boolean
  - object
    - `op` 'detach-parent', required
    - `confirm` string, required
  - object
    - `op` 'customize-page', required
    - `pageAssignmentId` string, required
  - object: Delete a variant override only when the real storefront resolver would serve a live, same-shop inherited page for the override's exact market/locale; otherwise 409 CONFLICT and the override is kept.
    - `op` 'revert-page', required
    - `pageAssignmentId` string, required
    - `confirm` string, required: Must equal the pageAssignmentId

## Response `200`

Operation result

- object

## Other responses

- `201`: Variant created
- `401`: Missing or invalid credentials
- `403`: Foreign project or missing scope (INSUFFICIENT_SCOPE)
- `404`: Not found (never discloses other tenants)
- `409`: CONFLICT: invalid hierarchy transition (maximum depth, project name already exists, circular link, not a variant, page already customized, or no inherited page to revert to); nothing was changed

---

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